事务管理似乎不适用于 Spring 测试
Posted
技术标签:
【中文标题】事务管理似乎不适用于 Spring 测试【英文标题】:Transaction management doesn't appear to work on Spring Tests 【发布时间】:2016-03-30 19:12:43 【问题描述】:我希望在使用@Transactional
的方法完成后将数据写入数据库。在使用 HSQL 数据库时,这是我的 JUnit 测试的有效假设吗?我使用 HSQL db 进行开发,使用 Oracle 进行部署的应用程序。 Web App 部署在 WebSphere 上,使用 RSA 开发。
下面是我的配置总结,包括 POM 和 junit 测试:
POM:
3.2.9.RELEASE
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.3</version>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.1</version>
APPLICATION CONTEXT:
<!-- the bean for transaction manager for scoping/controlling the transactions -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbDataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<jee:jndi-lookup id="dbDataSource" jndi-name="jndi/HSQLDatasource" expected-type="javax.sql.DataSource" />
<!--Mapper-->
<bean id="campaignMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface"
value="com.abc.persistence.mapper.CampaignMapper" />
<property name="sqlSessionTemplate">
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactoryForBatch" />
<constructor-arg index="1" value="BATCH" />
</bean>
</property>
</bean>
<!-- SqlSessionFactory For Batch -->
<bean id="sqlSessionFactoryForBatch" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dbDataSource" />
<property name="typeAliasesPackage" value="com.abc" />
<property name="mapperLocations" value="classpath*:com/mybatis/mappers/**/*.xml" />
</bean>
JUNIT:
//junit class extends a base class that initializes HSQL db
//jdbcConnection.setAutoCommit(false);
@Autowired
CampaignMapper campaignMapper;
@Transactional
@Test
public void testInsert()
for(Campaign record:campaignsFromFile)
record.setRowLastUpdateId(rowLastUpdateId);
record.setCampaignId(campaignId);
campaignMapper.insertCampaignRecord(record);
//At this point I expect that the data would NOT be written to the database
//other method code
//end of method
//At this point I expect that the data would be written to the database
【问题讨论】:
【参考方案1】:默认情况下,Spring 会在测试上下文中回滚事务。如果这不是您期望的行为,您始终可以使用 @Rollback
注释和 false
值:
@Transactional
@Test
@Rollback(false)
public void testInsert() ...
如果您使用的是 Spring 4.2.x 版本,则可以使用新的 @Commit
注释,这是一个可以直接替代 @Rollback(false)
的新注释。您可以在 Spring 测试上下文 here 中阅读有关 事务管理 的更多信息。
【讨论】:
我的期望是在方法退出之前不应将记录写入数据库。但是,如果我在调试中运行,在插入后放置一个断点并在每次插入后查询数据库(在循环中),我会看到一条一条写入数据库的各个记录。我的期望是只有在方法完成后才应该编写它们。感谢您对@Rollback 的见解,因为在我第一次更正这个其他问题后知道它会很有用。 然后删除Transactional
和Rollback
并使用TestTransaction
抽象手动管理事务。您可以使用start
、end
和flagForCommit
方法。
抱歉,现在我很困惑。因此,如果我正确阅读了此评论,我将无法测试我打算使用的代码。我不能使用事务性。我必须用 TestTranaction 替换它。我希望这是在 junit 测试中使用的 Transactional 的直接替换注释,但情况似乎并非如此。我在 TestTranaction 上搜索了帮助,但没有得到任何有用的信息。如果它是完全不同的东西,那么如果我无法在我的开发环境中检查它的行为,我不知道我在部署它时如何对我的代码有信心。
我想我可以将本地应用服务器连接到 oracle db 并从那里调试代码。这是我唯一可行的选择吗?以上是关于事务管理似乎不适用于 Spring 测试的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data REST 似乎不适用于 elasticsearch
提交的 JDO 写入不适用于本地 GAE HRD,或可能重用的事务