TransactionTemplate vs @Transactional(propagation = Propagation.REQUIRES_NEW)

时间:2012-04-28 08:06:51

标签: spring hibernate

有人可以解释为什么第一个单元测试类有效,而第二个测试类失败并出现锁定等待超时错误?

第一个测试类:

public class Test1 extends AbstractTransactionalJUnit4SpringContextTests {

    @Before
    public void setUp() {
       // do stuff through hibernate to populate database with test data
    }

    @Test
    @Transactional(propagation = Propagation.NEVER)
    public void testDeleteObject() {

    TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            try {
               // execute sql that deletes data populated in setUp() [i.e. this will require locks on the objects].
            }
        });
    }
}

第二个测试类[获取锁定等待超时错误]:

public class Test2 extends AbstractTransactionalJUnit4SpringContextTests {

    @Before
    public void setUp() {
       // do stuff through hibernate to populate database with test data
    }

    @Test
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void testObject() {

    // execute sql that deletes data populated in setUp() [i.e. this will require locks on the objects].

    }
}

我理解第二个测试类失败是因为两个事务正在为同一个锁争用,但由于它的in_progress事务状态,它们都不能放弃锁。我很困惑的是为什么第一个测试类成功执行sql。我可能理解这个错误,但是当transactionTemplate执行事务回调时,是否也没有创建新事务?在那种情况下,不应该发生同样的事情(锁定等待超时)?

2 个答案:

答案 0 :(得分:1)

仅当有两个或更多连接访问相同数据时才会发生死锁。如果使用传播NEVER注释的测试用例,您只有一个事务,一个由TransactionTemplate创建。

第二种情况对我来说有点模糊。异常意味着有两个并发连接/事务 - 一个用于setUp,另一个用于testObject。传播REQUIRES_NEW确实强制执行另一个连接,即使检测到一个连接,但我希望在此事务中也可以启动setUp。您可以尝试在@Transactional上删除testObjectAbstractTransactionalJUnit4SpringContextTests使用@Transactional进行注释,默认传播为REQUIRED我相信。

答案 1 :(得分:1)

默认情况下,TransactionTemplate不会创建新事务。默认传播行为是PROPAGATION_REQUIRED。在第一种情况下,没有锁定问题,因为设置和删除是在同一事务中完成的。

您可以通过为类org.springframework.orm.jpa.JpaTransactionManager(甚至整个org.springframework包)将日志级别设置为DEBUG来查看何时创建新事务或重用现有事务。

Javadoc for Propagation behaviour of TransactionTemplate