我有一个Spring / JDBC应用程序,它严重依赖于单元测试的MySQL回滚。我发现,如果在这些事务中执行某些DDL操作--即使是在临时表上--回滚甚至在正常的DML语句上也会失败。例如:
@Test
@Rollback(true)
public void testRollbackProblem() {
template.update("create temporary table foo (id INTEGER )");
template.update("update forms set form_name = 'blah' where form_id = 1412");
template.update("alter table foo add (name text)");
}测试完成后,该中间语句将被持久化,而不会回滚。有什么办法可以防止这种情况吗?也许某些参数传递给alter语句?
发布于 2017-03-20 15:59:51
据我所知,这是MySQL的限制。CREATE TABLE和ALTER TABLE语句导致隐式提交,不能回滚:
InnoDB中的CREATE语句作为单个事务处理。这意味着用户的回滚不会撤消用户在该事务处理期间所做的CREATE语句。
还请参阅MySQL文档:https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
更新的:因为您使用的是CREATE TEMPORARY TABLE,所以它实际上不应该执行隐式提交,但它的发生是因为在执行ALTER TABLE时
如果使用了临时关键字,则CREATE和DROP语句不提交事务。(这不适用于临时表上的其他操作,如ALTER 和CREATE,这些操作确实会导致提交。)但是,尽管没有发生隐式提交,但语句也不能回滚,这意味着使用此类语句会导致事务原子性受到侵犯。例如,如果使用CREATE临时表,然后回滚事务,则该表仍然存在。
https://stackoverflow.com/questions/42907288
复制相似问题