Spring 测试事务注释不起作用
Spring Test Transactional annotation not working
我在使用事务支持对 运行 进行测试时遇到问题。
重现方法如下:
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 在标记行中失败
尽管 Spring 的文档清楚地说明使用 @Transactional
注释的测试将导致在交易中对 运行 进行测试:
我的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>
相关问题:
编辑:日志显示:
2016-01-08 15:38:31,832 DEBUG [org.springframework.orm.jpa.JpaTransactionManager:367] - Creating new transaction with name ...
所以我相信确实创建了一个事务,但无法通过 TransactionAspectSupport.currentTransactionStatus()
读取它的状态,因为 Spring 仅读取 @Transactional
注释,但不会检测测试方法,因此不会绑定/取消绑定 TransactionAspectSupport
内的交易。如果是这样,我认为这可能是一个错误或至少是一个理想的功能。
所以我认为 TransactionAspectSupport.currentTransactionStatus() 不应该被使用。相反:
TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.isCurrentTransactionReadOnly();
应该使用(在测试和代码中),因为 TransactionAspectSupport 实际上只适用于使用 @Transactional 注释的 bean,而不是使用该注释的测试,并且没有其他使用事务的方式。
因此 Spring 更好的建议是弃用 public 方法 TransactionAspectSupport.currentTransactionStatus(),因为它是 bug-prone.
我在使用事务支持对 运行 进行测试时遇到问题。
重现方法如下:
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 在标记行中失败
尽管 Spring 的文档清楚地说明使用 @Transactional
注释的测试将导致在交易中对 运行 进行测试:
我的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>
相关问题:
编辑:日志显示:
2016-01-08 15:38:31,832 DEBUG [org.springframework.orm.jpa.JpaTransactionManager:367] - Creating new transaction with name ...
所以我相信确实创建了一个事务,但无法通过 TransactionAspectSupport.currentTransactionStatus()
读取它的状态,因为 Spring 仅读取 @Transactional
注释,但不会检测测试方法,因此不会绑定/取消绑定 TransactionAspectSupport
内的交易。如果是这样,我认为这可能是一个错误或至少是一个理想的功能。
所以我认为 TransactionAspectSupport.currentTransactionStatus() 不应该被使用。相反:
TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.isCurrentTransactionReadOnly();
应该使用(在测试和代码中),因为 TransactionAspectSupport 实际上只适用于使用 @Transactional 注释的 bean,而不是使用该注释的测试,并且没有其他使用事务的方式。
因此 Spring 更好的建议是弃用 public 方法 TransactionAspectSupport.currentTransactionStatus(),因为它是 bug-prone.