2

我正在尝试使用 Spring 提供的声明性事务管理功能。我已经按照参考文档中的描述设置了 spring 配置和 bean(即包括 AOP、tx 命名空间和使用<tx:annotation-driven />标签),并且在我想要成为事务性的方法上使用了 @Transactional 注释。

这是代码的样子:

public interface Worker {
    public workOnEvents(List<Events> eventsForACustomer);
}

public class WorkerImpl {
    @Transactional
    public workOnEvents(List<Events> eventsForACustomer) {
        for(Event event : eventsForACustomer) {
            // get DAO's based on event types at runtime,
            // so we will have different DAO's acting within this loop
            DAOFactory.getDAO(event.getType()).persistEvent(event);
        }
    }
}

现在,我希望如果上述循环中的任何 DAO 无法处理该事件,那么在此之前进入循环的其他 DAO 对数据库所做的所有更改都应该回滚。

因此,为了测试回滚,我列出了一些事件的列表,例如 (e1, e2, e3),这会导致拾取 DAO,例如 (d1, d2, d3),然后我故意在persistEvent 方法中抛出运行时异常道 d2。但是,我得到的结果是程序终止而没有转到循环中的事件 e3,也没有处理抛出的异常。此外,DAO d1 持久化的数据不会回滚。

请让我知道我在这里做错了什么?

4

4 回答 4

1

注释方法不会满足您对应该发生的事情的期望。它的工作方式是注解将方法标记为 Spring 应用通知的东西,并且通知包装了方法,因此可以在调用方法之前发生一些事情,比如开始一个新事务,以及在方法完成之后,比如提交或回滚事务。当您描述要回滚 e1 和 e2 时,应该提交 e3 ,这将需要在方法中间执行事务代码,因此为此使用建议是行不通的。

对于您想要的事务控制级别,您将不得不求助于Spring 的编程事务 API

编辑:查看您的评论,我可能误解了您想要的内容。如果您可以确定要一起处理的一组事物(全部或全部),则可以将它们组合在一个标记为事务性的方法中,并具有一个非事务性方法,该方法在具有异常处理的循环中调用该方法围绕事务方法的每次调用。

于 2010-03-05T21:57:43.440 回答
0

您需要在注解中添加一个 RollbackFor 属性。像这样的东西:@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Throwable.class)

于 2010-03-05T06:02:12.350 回答
0

默认情况下,仅回滚未经检查的异常(即 java.lang.RuntimeException 的子类)。

您需要将rollbackFor添加到 @Transactional 注释。

您也没有异常处理,因此 e3 不会被执行。

于 2010-03-05T06:06:03.653 回答
0

可能您已经提交了前一个事务,因此 Java 部分不能再回滚它。

我猜要么:

  • 您的数据库提交每次插入/更新
  • 你的 DAO 做到了
于 2010-03-05T06:30:56.037 回答