Spring JUnit期间的数据库死锁与之前的sql

时间:2017-08-29 12:10:10

标签: java sql-server spring junit deadlock

在我的SpringBoot应用程序中,我有一个简单的测试用例,我想要这个: 在测试之前将一些数据插入数据库 在测试中做一些验证 测试后从数据库中删除数据 这就是我写它的方式:

保存sql-s的接口。

@Target(METHOD)
@Retention(RUNTIME)
@Sql(scripts = "/insert-data-before.sql", config = @SqlConfig(transactionMode = ISOLATED), executionPhase = BEFORE_TEST_METHOD)
@Sql(scripts = "/delete-data-after.sql", config = @SqlConfig(transactionMode = ISOLATED), executionPhase = AFTER_TEST_METHOD)
public @interface PrepareAndRollbackDataForTesting {
}

测试类:

@RunWith(SpringRunner.class)
@ConfigurationProperties(prefix = "server")
@SpringBootTest(classes = MyTestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@Transactional
public abstract class MyTestClass {
    @Test
    @PrepareAndRollbackDataForTesting
    public void testTheData() {
        //do something
    }
}

插入数据-before.sql:

BEGIN TRANSACTION;
INSERT INTO mytable(id, name) VALUES (1, 'test');
COMMIT;

删除数据-after.sql:

BEGIN TRANSACTION;
DELETE FROM mytable;
COMMIT;

但如果我这样写,它最终将会出现在死锁中。

如果从界面删除delete-data-after.sql @Sql,它可以正常工作!

此外,如果我从界面中删除@ Sql-s中的配置,它可以正常工作!

但是我想在一个单独的事务中运行insert和delete sql,以确保它会删除所有数据,无论方法内部发生什么,即使是异常情况!

1 个答案:

答案 0 :(得分:0)

我发现了!

我只需从界面中删除配置:

@Target(METHOD)
@Retention(RUNTIME)
@Sql(scripts = "/insert-data-before.sql", executionPhase = BEFORE_TEST_METHOD)
@Sql(scripts = "/delete-data-after.sql", executionPhase = AFTER_TEST_METHOD)
public @interface PrepareAndRollbackDataForTesting {
}

因为@Transactional注释将处理事务,并且之后将回滚。

修改

我还从sqls中删除了BEGIN TRANSACTION和COMMIT thingy。