上一节概述了如何在你的应用程序中以声明的方式为类(通常是服务层类)指定事务性设置的基本知识。本节描述了如何以简单的声明方式控制事务的回滚。

    向 Spring 框架的事务基础架构表明事务工作将被回滚的推荐方法是,从 当前在事务上下文中执行的代码中抛出一个异常。Spring 框架的事务基础架构代码会在调用堆栈中捕获任何未处理的异常,并决定是否对事务进行回滚标记。

    在其默认配置中,Spring 框架的事务基础架构代码只在 运行时未检查的异常 情况下标记事务进行回滚。也就是说,当抛出的异常是RuntimeException 的一个实例或子类时。(Error 实例默认也会导致回滚)。在默认配置中,从事务方法抛出的检查异常不会导致回滚。

    你可以准确地配置哪些异常类型将事务标记为回滚,包括检查的异常。下面的 XML 片段演示了如何为一个被检查的、特定于应用程序的 Exception 类型配置回滚:

    1. <tx:advice id="txAdvice" transaction-manager="txManager">
    2. <tx:attributes>
    3. <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
    4. <tx:method name="*"/>
    5. </tx:attributes>
    6. </tx:advice>

    如果你不希望事务在抛出异常时被回滚,你也可以指定 「no rollback rules / 无回滚规则」。下面的例子告诉 Spring 框架的事务基础架构,即使面对未处理的 InstrumentNotFoundException,也要提交相关的事务:

    1. <tx:advice id="txAdvice">
    2. <tx:attributes>
    3. <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
    4. <tx:method name="*"/>
    5. </tx:attributes>
    6. </tx:advice>

    当 Spring 框架的事务基础架构捕捉到一个异常,并咨询配置的回滚规则以确定是否将事务标记为回滚,最强的匹配规则获胜。因此,在下面的配置中,除了 InstrumentNotFoundException 之外的任何异常都会导致相关事务的回滚。

    1. <tx:advice id="txAdvice">
    2. <tx:attributes>
    3. <tx:method name="*" rollback-for="Throwable" no-rollback-for="InstrumentNotFoundException"/>
    4. </tx:attributes>
    5. </tx:advice>

    你也可以用编程方式表示需要回滚。虽然简单,但这一过程是相当具有侵入性的,它将你的代码与 Spring 框架的事务基础结构紧密地联系在一起。下面的例子展示了如何以编程方式指示所需的回滚:

    1. public void resolvePosition() {
    2. try {
    3. // 一些业务逻辑...
    4. } catch (NoProductInStockException ex) {
    5. // 以编程方式触发回滚
    6. TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    7. }
    8. }

    如果可能的话,我们强烈建议你使用声明式方法来回滚。如果你绝对需要的话,可以使用程序化回滚,但它的使用与实现一个干净的基于 POJO 的架构相冲突。