【问题标题】:MySQL Alter table prevents rollback of DML (?)MySQL Alter 表防止回滚 DML (?)
【发布时间】:2017-03-20 15:14:45
【问题描述】:

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

【问题讨论】:

    标签: mysql spring jdbc


    【解决方案1】:

    据我所知,这是 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 然后回滚事务,则该表仍然存在。

    【讨论】:

    • 但仍然可以使用 JUnit 中的 @Before/@After@BeforeClass/@AfterClass 作为解决方法。
    • 是的。但我希望在测试中使用它的原因是能够以编程方式验证结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多