Spring Boot JDBCTemplate с MySQL и проблемой фиксации и отката Maria DB - PullRequest
0 голосов
/ 11 июля 2020

Я использую платформу Spring Boot с JDBCTemplate для доступа к базе данных. Я использую аннотацию транзакций для принудительного выполнения транзакций для вызовов БД.

@Transactional(rollbackFor = IllegalStateException.class, propagation = Propagation.REQUIRES_NEW)

С Maria DB я вижу, что ниже регистрируется последовательность транзакций и мои откаты транзакций, и ничего не фиксируется.

o.s.j.d.DataSourceTransactionManager     : Creating new transaction with name [Test]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,-java.lang.IllegalStateException
o.s.j.d.DataSourceTransactionManager     : Acquired Connection [HikariProxyConnection@368558459 wrapping org.mariadb.jdbc.MariaDbConnection@3e839aa3] for JDBC transaction
o.s.jdbc.core.JdbcTemplate               : Executing SQL statement [INSERT INTO test (Col1,Col2) values(1,'ABC')]
o.s.j.d.DataSourceTransactionManager     : Initiating transaction rollback
o.s.j.d.DataSourceTransactionManager     : Rolling back JDBC transaction on Connection [HikariProxyConnection@368558459 wrapping org.mariadb.jdbc.MariaDbConnection@3e839aa3]
o.s.j.d.DataSourceTransactionManager     : Releasing JDBC Connection [HikariProxyConnection@368558459 wrapping org.mariadb.jdbc.MariaDbConnection@3e839aa3] after transaction

Однако с базой данных MySQl 5.1 я могу видеть в журналах, что транзакция откатывается, но изменения БД все еще фиксируются.

В режиме отладки я смог увидеть шаблон JDB C момента .execute происходит, когда записи фиксируются, и trscationManager получает уведомление об откате, поскольку я выбрасываю явное проверенное исключение и определяю.

Почему откат не происходит с MySQL, но происходит в MariaDB? My SQL LOG Trail

DataSourceTransactionManager     : Creating new transaction with name [TEST]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 'jdbcDataSourceTransactionManager'

DataSourceTransactionManager  : Acquired Connection [HikariProxyConnection@436329238 wrapping 
com.mysql.jdbc.JDBC4Connection@2b464384] for JDBC transaction
JdbcTemplate               : Executing prepared SQL update

JdbcTemplate               : Executing prepared SQL statement [INSERT INTO TEST (dataNetwork,start, end, type, directory, rank) values(?, ?, ?,?,?,?)]

DataSourceTransactionManager     : Initiating transaction rollback

DataSourceTransactionManager     : Rolling back JDBC transaction on Connection [HikariProxyConnection@436329238 wrapping 

com.mysql.jdbc.JDBC4Connection@2b464384]
DataSourceTransactionManager     : Releasing JDBC Connection [HikariProxyConnection@436329238 wrapping 

com.mysql.jdbc.JDBC4Connection@2b464384] after transaction
DispatcherServlet        : Failed to complete request: 
java.lang.RuntimeException: To Test Roll Back

Код метода обслуживания:

@Transactional(transactionManager = "jdbcDataSourceTransactionManager")
public void copyDataNetwork(WorkingFolderCopyRequest workingFolderCopyRequest,
      DataNetworkTransaction transaction) throws RuntimeException {
    dataNetoworkDao.copy(DataNetworkTables.DATA_NETWORK.getTableName(),
       DataNetworkTables.DATA_NETWORK.getColumnName(),
        workingFolderCopyRequest.getSource(), 
 workingFolderCopyRequest.getDestination());

    throw new RuntimeException("To Test Roll Back");
}

DataNetworkDAO

@Repository
public class DataNetworkDAO  {

    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    DataSource dataSource;

    public DataNetworkDaoImpl(@Qualifier("ooretaDataSource")DataSource dataSource) {
        this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public void copy(String tableName, String dataNetworkColumn, String oldNetworkName, String newNetworkName) {
        String sql = "INSERT INTO TEST (dataNetwork,start, end, type, directory, rank) values(:dataNetwork, :start, :end,:type,:directory,:rank)";
        Map<String, Object> params = new HashMap<>();
        params.put("dataNetwork", "WF20");
        params.put("start", "2");
        params.put("end", "");
        params.put("type", "T");
        params.put("directory", "Temp");
        params.put("rank", 0);

        jdbcTemplate.update(sql, params);
        
    }
}

DataSource Config

HikariPool-2 - конфигурация: allowPoolSuspension ........... ..false autoCommit ...................... false HikariPoo l-2 - Запуск ... HikariPool-2 - Добавлено соединение com. mysql .jdb c. JDBC4Connection@608eb42e HikariPool-2 - Запуск завершен.

ohejeiJdbcEnvironmentInitiator: База данных -> имя: MySQL версия: 5.1.73-основное сообщество: 5 второстепенное: 1

ohejeiJdbcEnvironmentInitiator: Driver -> имя: MySQL Connector Java версия: mysql -connector- java -5.1.25 ( Редакция: $ {bzr.revision-id}) major: 5 minor: 1

1 Ответ

2 голосов
/ 14 июля 2020

После всех усилий я нашел причину. Счастье программиста, которое я получил в это время COVID.

MySql имеет 2 ядра БД MyISAM и InnoDB. Эта устаревшая БД содержит все таблицы с движком MyISAM. Механизм MyISAM не поддерживает транзакции. Вы не можете откатиться.

Если мы используем SHOW TABLE STATUS; затем он покажет, какая таблица с каким типом движка, а затем нам нужно изменить движок таблицы, как показано ниже, чтобы получить поддержку транзакций.

ALTER TABLE < > ENGINE = 'InnoDB';

И, наконец, откат сработал как шарм.

Ссылка для получения дополнительной информации:

http://ronaldbradford.com/blog/using-rollback-with-myisam-2010-03-31/#: ~: text = Двигатель% 20MySQL% 20default% 20storage% 20, на% 20the% 20delta% 20over% 20time .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...