Spring MVC 4服务@tTransactional不起作用

时间:2016-02-10 06:52:41

标签: java spring spring-mvc

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不起作用?

3 个答案:

答案 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()来强制提交此事务或回滚。