我正在使用Spring编写应用程序。我想把我的JDBC代码写成事务性的,我可以通过使用AOP来实现:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" rollback-for="MyCustomException"/>
<tx:method name="*" rollback-for="MyCustomException" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pc" expression="execution(* com.me.jdbc.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />
</aop:config>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="simpleDataSource" />
</bean>
<bean id="simpleDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="username" value="sa" />
<property name="password" value="" />
<property name="url" value="jdbc:h2:mem:aas;MODE=Oracle;DB_CLOSE_DELAY=-1;MVCC=true" />
</bean>
因此,如果发生MyCustomException,com.me.jdbc中的所有方法都应该是事务性的和回滚的。到目前为止这是有效的。
我现在想编写一个单元测试,但是我希望我的单元测试是事务性的,这样一旦测试完成,整个事务就会回滚并使数据库保持原样。
我能够通过宣布:
来实现这一目标@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
@Transactional
在我的Test课上。然而问题是我丢失了应用程序代码上的事务,即在每次测试之后事务被回滚,但是如果应用程序代码中发生异常,则插入不会回滚而我的单元测试失败,因为我希望表格能够是空的,但事实并非如此。
我如何实现这两个级别的交易?可能吗?我可以通过为我的单元测试编写一个设置方法来解决这个问题,该方法在每次测试之前清除所有表。我对此很好,但我认为能够使用回滚方法实现同样的事情会很好。
答案 0 :(得分:0)
正如评论部分所述,问题在于通过使测试方法封装事务,只有在测试抛出异常时才会发生回滚。这使得在抛出异常之前无法验证测试中的行为。我已经采用了在安装方法中清空所有表的方法(在每次测试之前)。