spring事务传播机制

spring声明式事务管理时定义了7种传播机制

    /**
     * Support a current transaction, create a new one if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p>This is the default setting of a transaction annotation.
     * 支持当前事务,如果没有创建一个新的
     */
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

    /**
     * Support a current transaction, execute non-transactionally if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p>Note: For transaction managers with transaction synchronization,
     * PROPAGATION_SUPPORTS is slightly different from no transaction at all,
     * as it defines a transaction scope that synchronization will apply for.
     * As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)
     * will be shared for the entire specified scope. Note that this depends on
     * the actual synchronization configuration of the transaction manager.
     * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization
     * 支持当前事务,如果没有就不使用事务管理
     */
    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

    /**
     * Support a current transaction, throw an exception if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * 支持当前事务,如果没有抛出异常
     */
    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

    /**
     * Create a new transaction, and suspend the current transaction if one exists.
     * Analogous to the EJB transaction attribute of the same name.
     * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
     * on all transaction managers. This in particular applies to
     * {@link org.springframework.transaction.jta.JtaTransactionManager},
     * which requires the {@code javax.transaction.TransactionManager} to be
     * made available it to it (which is server-specific in standard Java EE).
     * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
     * 创建一个新的事务,如果当前存在事务就将当前的事务挂起
     */
    REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

    /**
     * Execute non-transactionally, suspend the current transaction if one exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box
     * on all transaction managers. This in particular applies to
     * {@link org.springframework.transaction.jta.JtaTransactionManager},
     * which requires the {@code javax.transaction.TransactionManager} to be
     * made available it to it (which is server-specific in standard Java EE).
     * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
     * 不使用事务管理,如果当前存在事务就挂起
     */
    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

    /**
     * Execute non-transactionally, throw an exception if a transaction exists.
     * Analogous to EJB transaction attribute of the same name.
     * 不使用事务管理,如果当前存在事务就抛出异常
     */
    NEVER(TransactionDefinition.PROPAGATION_NEVER),

    /**
     * Execute within a nested transaction if a current transaction exists,
     * behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.
     * <p>Note: Actual creation of a nested transaction will only work on specific
     * transaction managers. Out of the box, this only applies to the JDBC
     * DataSourceTransactionManager when working on a JDBC 3.0 driver.
     * Some JTA providers might support nested transactions as well.
     * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
     * 如果当前存在事务就创建一个内嵌事务,在内嵌事务中运行,如果当前没有事务就和     
     * PROPAGATION_REQUIRED 一样处理
     */
    NESTED(TransactionDefinition.PROPAGATION_NESTED);

除了NESTED与REQUIRES_NEW,其余五种看注释就很好理解,
REQUIRES_NEW与NESTED均需要创建一个新的事务,但REQUIRES_NEW是创建一个全新的事务,与当前事务没有关联,REQUIRES_NEW的事务的提交回滚只会对自己有效,当前事务的提交回滚也与REQUIRES_NEW下的代码无关,即当前事务如果回滚的话不会去回滚REQUIRES_NEW下的部分。NESTED不同,NESTED是一个内嵌事务,该事务完成时并不会真正的提交事务,只有当前事务提交时NESTED事务才会真正提交,即当前事务如果回滚也会将NESTED事务回滚,但NESTED自身的回滚只会回滚到调用NESTED部分的代码,这点与REQUIRES_NEW的逻辑相同

注意spring声明式事务管理默认情况下是不支持NESTED的,如果需要支持NESTED需要添加如下配置:
nestedTransactionAllowed的默认值为false,需要设置为true

<bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="nestedTransactionAllowed" value="true"></property>
    </bean>

还有一点需要注意的是spring的事务传播机制只会对调用不同的类下的方法起作用,如果是同一个类下的方法调用,并不会使用spring的事务传播机制,此时整个事务管理都依赖于最初的入口方法的事务管理,如果该方法没有事务管理,则均不使用事务管理(限调用方法均为该类内部),如果入口方法有事务管理则所有调用方法都使用这个事务管理(同样限调用方法均为该类内部方法),如果入口方法或者入口方法调用的方法调用了其他类的方法,则其他类方法的事务管理机制按照spring事务传播机制来执行。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值