【问题标题】:Spring Test Transactional annotation not workingSpring Test 事务注释不起作用
【发布时间】:2016-01-08 14:15:03
【问题描述】:

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

这是一种重现的方法:

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 内。如果是这样,我认为这可能是一个错误或至少是一个理想的功能。

【问题讨论】:

  • 他们会,但前提是TransactionalTestExecutionListener 存在于ContextConfigLocation 中,但事实并非如此。因此没有交易,基本上你的@Transactional is useless. Also why do you specify your test case as a configuration class, because it isn't... Just load the xml (like the one you commented out). Suggestion remove @Transactional, @Rollback, @ImportResource`和@RunWith和扩展AbstractTransactionalJUnit4SpringContextTests代替。并更改 @ContextConfiguration 以改为加载 xml。
  • 我尝试了不同的变体,也是您建议的变体,但没有变化。我在最后添加了一个编辑,这可能会解决问题。
  • 首先修复你的设置,因为它并不是你应该如何做的事情。我也想知道你到底为什么要测试这样的东西?
  • 设置是否脏与bug无关,只要设置有效即可。我对此进行了测试,因为我有一个与依赖 TransactionAspectSupport 的代码相关的错误。

标签: java spring jpa testing transactions


【解决方案1】:

所以我相信永远不应该使用 TransactionAspectSupport.currentTransactionStatus()。而是:

    TransactionSynchronizationManager.isActualTransactionActive();
    TransactionSynchronizationManager.isCurrentTransactionReadOnly();

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

因此,对 Spring 的更好建议是弃用公共方法 TransactionAspectSupport.currentTransactionStatus(),因为它容易出错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-01
    • 2014-06-12
    • 2019-07-15
    • 2011-11-20
    • 2017-06-10
    • 2018-03-22
    • 2014-08-14
    • 1970-01-01
    相关资源
    最近更新 更多