1. Spring MVC application-context.xml
<tx:annotation-driven/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="test"/>
<property name="password" value="test"/>
<property name="url" value="jdbc:mysql://localhost:13306/test"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
2. Service impl class
@Override
@Transactional
public void deleteCommentAndFiles(int commentId) {
int deletedCommentCount = commentDAO.deleteComment(commentId);
int deletedFileCount = fileDAO.deleteFiles(commentId);
if (deletedCommentCount != 1) {
throw new IncorrectUpdateSemanticsDataAccessException("Deleted comment not 1 [deletedCount : " + deletedCommentCount);
}
if (deletedFileCount != 1) {
throw new IncorrectUpdateSemanticsDataAccessException("Deleted file not 1 [deletedCount : " + deletedCommentCount);
}
}
3. Test Case
@Test
public void rollbackT() {
boolean hasException = false;
int sizeBeforDelete = commentDAO.selectCountByArticle(1);
try {
commentService.deleteCommentAndFiles(1);
} catch (RuntimeException e) {
hasException = true;
}
Assert.assertTrue(hasException);
Assert.assertEquals(sizeBeforDelete, commentDAO.selectCountByArticle(1));
}
在测试用例中
首先传递Assert.assertTrue(hasException);
,但
Assert.assertEquals(sizeBeforDelete, commentDAO.selectCountByArticle(1))
此案例失败Expected : 1 but Actual : 0
此第二个TC失败意味着发生异常,但不回滚删除注释
deleteCommentAndFiles method
抛出异常但不回滚
我正在尝试使用@Transactional(propagation=Propagation.REQUIRED, rollbackFor={IncorrectUpdateSemanticsDataAccessException.class})
但同样不起作用
为什么@Transactional annotaion不起作用?
答案 0 :(得分:2)
我也有同样的问题。我将@transactional移动到控制器以便工作。
@EnableTransactionManagement并且只在它们定义的相同应用程序上下文中查找bean上的@Transactional。这意味着,如果在WebApplicationContext中为DispatcherServlet添加注释驱动配置,它只检查控制器中的@Transactional bean ,而不是你的服务。有关更多信息,请参见第21.2节“DispatcherServlet”。
答案 1 :(得分:1)
数据库必须支持事务。在MySQL的情况下,您需要创建一个类型为InnoDB,BDB或Genini的表。
默认myisam不支持交易。
答案 2 :(得分:1)
我没有看到你的主要测试类,但我假设你使用junit的默认弹簧配置:
默认情况下,会在自己的隐式事务上启动测试。当你打电话给你的服务时,它会启动一个&#34; sub&#34;逻辑事务(这是测试事务的一部分,因为您没有使用require_new进行传播)。当此事务失败时,主事务被标记为回滚,但是直到主事务完成,测试结束时才进行回滚
如果要测试回滚,则不应使用由测试框架启动的此隐式事务,或者可以在断言之前使用TestTransaction.end()
来强制提交此事务或回滚。