MySQL Alter表阻止DML的回滚(?)

时间:2017-03-20 15:14:45

标签: mysql spring jdbc

我有一个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语句?

1 个答案:

答案 0 :(得分:2)

据我所知,这是MySQL的限制。 CREATE TABLEALTER TABLE语句导致隐式提交,无法回滚:

  

InnoDB中的CREATE TABLE语句作为单个事务处理。这意味着来自用户的ROLLBACK不会撤消用户在该事务期间所做的CREATE TABLE语句。

另见MySQL文档:https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

<强>更新: 因为你正在使用CREATE TEMPORARY TABLE它实际上不应该进行隐式提交,但是因为当你执行ALTER TABLE时会发生这种情况:

  

如果使用TEMPORARY关键字,则CREATE TABLE和DROP TABLE语句不提交事务。 (这不适用于临时表上的其他操作,例如ALTER TABLE 和CREATE INDEX,它们会导致提交。)但是,虽然没有发生隐式提交,但是语句也不能回滚,意味着使用此类语句会导致违反事务原子性。例如,如果使用CREATE TEMPORARY TABLE然后回滚事务,则该表仍然存在。