Spring Test Transactional注释不起作用

时间:2016-01-08 14:15:04

标签: java spring jpa testing transactions

我在使用事务支持运行测试时遇到问题。

这是一种重现方式:

import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.transaction.SystemException;

@ContextConfiguration("classpath:applicationContext-hibernate-test.xml")
public class TransactionsTest extends AbstractTransactionalJUnit4SpringContextTests {

  @Transactional
  @Test
  public void testTransactionEnabled() throws SystemException {
    assert TransactionSynchronizationManager.isActualTransactionActive(); // works
    assert ! TransactionSynchronizationManager.isCurrentTransactionReadOnly(); // works
    assert TransactionAspectSupport.currentTransactionStatus() != null; // fails
  }
}

将屈服:

  • testTransactionEnabled在标记行中失败

尽管Springs文档明确指出用@Transactional注释的测试会导致测试在事务中运行:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#testcontext-tx-enabling-transactions

我的applicationContext-hibernate-test.xml:

<beans...>
  <jdbc:embedded-database id="dataSource" type="H2" />
  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >...
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
    </property>
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager" />

</beans>

相关问题: https://stackoverflow.com/questions/943095

编辑:日志说:

2016-01-08 15:38:31,832 DEBUG [org.springframework.orm.jpa.JpaTransactionManager:367] - Creating new transaction with name ...

所以我认为确实创建了一个事务,但它的状态无法通过TransactionAspectSupport.currentTransactionStatus()读取,因为Spring只读取@Transactional注释,但没有检测测试方法,因此不会在TransactionAspectSupport内绑定/取消绑定事务。如果是这样,我认为这可能是一个错误或至少是一个理想的功能。

1 个答案:

答案 0 :(得分:0)

所以我认为永远不要使用TransactionAspectSupport.currentTransactionStatus()。代替:

    TransactionSynchronizationManager.isActualTransactionActive();
    TransactionSynchronizationManager.isCurrentTransactionReadOnly();
应该使用

(在测试和代码中),因为TransactionAspectSupport实际上只适用于使用@Transactional注释的bean,而不是使用该注释进行测试,也没有其他方式使用事务。

因此,对Spring的一个更好的建议是不推荐使用公共方法TransactionAspectSupport.currentTransactionStatus(),因为它很容易出错。