Spring Boot JDBCTemplate with MySQL and Maria DB Commit and



我使用带有JDBCTemplate的Spring Boot框架进行数据库访问。我使用Transactional注释来强制执行DB调用的事务。

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

使用MariaDB,我可以看到下面的日志记录了事务的顺序和我的事务回滚,但没有提交任何内容。

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

然而,对于MySQL5.1数据库,我可以在日志中看到事务已回滚,但数据库更改仍在提交中。

在调试模式下,我能够看到JDBC template.execure调用发生的那一刻,记录被提交,trscationManager在我抛出显式CheckedException并定义时收到回滚通知。

为什么MySQL不会发生回滚,而MariaDB会发生回滚?

我的SQL日志跟踪

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);

}
}

数据源配置

HikariPool-2-配置:allowPoolSuspension。。。。。。。。。。。。。虚假的自动提交。。。。。。。。。。。。。。。。。。。。。。虚假的HikariPool-2-正在启动。。。HikariPool-2-增加了连接com.mysql.jdbc.JDBC4Connection@608eb42eHikariPool-2-启动完成。

o.h.e.j.e.JdbcEnvironmentInitiator:数据库->名称:MySQL版本:5.1.73-社区主要:5次要:1

o.h.e.j.e.JdbcEnvironmentInitiator:Driver->名称:MySQL连接器Java版本:MySQL-Connector-Java-5.1.25(修订版:${bzr.Revision-id}(主要:5次要:1

经过所有的挣扎,我找到了原因。程序员我在新冠肺炎疫情期间获得的快乐。

MySql有两个数据库引擎MyISAM和InnoDB。这个遗留数据库拥有所有带有MyISAM引擎的表。MyISAM引擎不支持事务。您不能回滚。

如果我们使用SHOW TABLE STATUS;然后它将显示哪个表使用哪个引擎类型,然后我们需要按照下面的方式更改表引擎以获得事务支持。

ALTER TABLE<lt;表名称>gt;ENGINE="InnoDB";

最后,回滚就像一个符咒

链接阅读更多:

http://ronaldbradford.com/blog/using-rollback-with-myisam-2010-03-31/#:~:text=%20MySQL%20默认的%20storage%20引擎,在%20增量%20超过%20时间。

最新更新