Spring TransactionTemplate vs@Transactional(传播=传播。需要\u新建)

Spring TransactionTemplate vs@Transactional(传播=传播。需要\u新建),spring,hibernate,Spring,Hibernate,有人能解释为什么第一个单元测试类工作,而第二个测试类由于锁等待超时错误而失败吗 第一级考试: public class Test1 extends AbstractTransactionalJUnit4SpringContextTests { @Before public void setUp() { // do stuff through hibernate to populate database with test data } @Test

有人能解释为什么第一个单元测试类工作,而第二个测试类由于锁等待超时错误而失败吗

第一级考试:

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].

    }
}

我知道第二个测试类失败是因为两个事务正在争夺相同的锁,但由于其正在进行的事务状态,两个事务都不能放弃锁。我感到困惑的是为什么第一个测试类成功地执行了sql。我可能理解错了,但是当transactionTemplate执行事务回调时,是否也会创建一个新事务?在这种情况下,是否应该发生相同的情况(锁定等待超时)?

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


第二个案例对我来说有点模糊。异常意味着有两个并发连接/事务-一个用于
setUp
,另一个用于
testObject
。传播
需要\u NEW
即使检测到另一个连接,也会强制执行另一个连接,但我希望
设置也会在该事务中启动。您可以尝试在
testObject
上删除
@Transactional
AbstractTransactionalJUnit4SpringContextTests
是用
@Transactional
本身注释的,默认传播是
必需的

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


对,那么在第一种情况下,既然测试类本身也用@Transactional注释,那么是否还有两个事务(一个事务通过运行testcase+安装程序启动,另一个事务通过TransactionTemplate启动)?第二种情况似乎也是如此,所以我可能不太理解这里的内容。方法上的
@Transactional
应该覆盖类上的
@Transactional
。如果从不使用传播,则不应创建任何事务,而应创建默认的必需传播。您应该能够通过org.springframework.transaction的调试级别日志来验证这一点。