聊聊Spring的事物传播行为

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ztx114/article/details/86691705

传播行为

传播行为是方法之间调用事务采取的策略问题。在绝大部分的情况下,我们会认为数据库事务要么全部成功,要么全部失败。但现实中也许会有特殊的情况。例如,执行一个批量程序,它会处理很多的交易,绝大部分交易是可以顺利完成的,但是也有极少数的交易因为特殊原因不能完成而发生异常,这时我们不应该因为极少数的交易不能完成而回滚批量任务调用的其他交易,使得那些本能完成的交易也变为不能完成了。此时,我们真实的需求是,在一个批量任务执行的过程中,调用多个交易时,如果有一些交易发生异常,只是回滚那些出现异常的交易,而不是整个批量任务,这样就能够使得那些没有问题的交易可以顺利完成,而有问题的交易则不做任何事情,如下图所示。
在这里插入图片描述
在 Spring 中,当一个方法调用另外一个方法时,可以让事务采取不同的策略工作,如新建事务或者挂起当前事务等,这便是事务的传播行为。这样讲还是有点抽象,我们再回到图6-5中。图中,批量任务我们称之为当前方法,那么批量事务就称为当前事务,当它调用单个交易时,称单个交易为子方法,当前方法调用子方法的时候,让每一个子方法不在当前事务中执行,而是创建一个新的事务去执行子方法,我们就说当前方法调用子方法的传播行为为新建事务。此外,还可能让子方法在无事务、独立事务中执行,这些完全取决于你的业务需求。

传播行为的定义

在 Spring 事务机制中对数据库存在7种传播行为,它是通过枚举类 Propagation 定义的。下面先来研究它的源码,如代码清单所示。
传播行为枚举代码清单

package org.springframework.transaction.annotation;
/**** imports ****/
public enum Propagation {
    /**
     * 需要事务,它是默认传播行为,如果当前存在事务,就沿用当前事务,
     * 否则新建一个事务运行子方法
     */
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

    /**
     * 支持事务,如果当前存在事务,就沿用当前事务,
     * 如果不存在,则继续采用无事务的方式运行子方法
     */
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

    /**
     * 必须使用事务,如果当前没有事务,则会抛出异常,
     * 如果存在当前事务,就沿用当前事务
     */
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

    /**
     * 无论当前事务是否存在,都会创建新事务运行方法,
     * 这样新事务就可以拥有新的锁和隔离级别等特性,与当前事务相互独立
     */
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

    /**
     * 不支持事务,当前存在事务时,将挂起事务,运行方法
     */
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

    /**
     * 不支持事务,如果当前方法存在事务,则抛出异常,否则继续使用无事务机制运行
     */
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

    /**
     * 在当前方法调用子方法时,如果子方法发生异常,
     * 只回滚子方法执行过的 SQL,而不回滚当前方法的事务
     */
    NESTED(TransactionDefinition.PROPAGATION_NESTED);

    private final int value;

    Propagation(int value) { this.value = value; }

    public int value() { return this.value; }
}

以上代码中加入中文注释解释了每一种传播行为的含义。传播行为一共分为7种。

猜你喜欢

转载自blog.csdn.net/ztx114/article/details/86691705
今日推荐