mysql学习笔记(五)图解事务传播行为

引言

本篇博文小猿主要是针对事务的应用,而事务的传播行为有7类,这7种传播行为各有不同的应用场景,以下小猿将论述7种传播行为各自的特点

函数关系

REQUIED

mysql学习笔记(五)图解事务传播行为

/**
	 * 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),

case1

mysql学习笔记(五)图解事务传播行为
上述图中最后一句写的不好,应该是两个children方法执行保存失败,而不是不执行。
mysql学习笔记(五)图解事务传播行为

case2

mysql学习笔记(五)图解事务传播行为
上述图中虽然在函数2中添加了事务,但应为函数1中已经有事务,而传播行为required,这说明当执行函数2时,看到函数1已经存在时候,则直接加入函数1的事务,自己就不再创建新事务,这种现象就是required事务的传播,此时无论函数是否有事务注解都无关紧要,子事务都会加入到父事务中, 按照事务的原子性,此时采用函数1的事务,则中间如果出现一次异常,这此次事务全部执行失败。
完全回滚。
mysql学习笔记(五)图解事务传播行为
require传播行为可以总结为老板有饭吃,我就蹭饭吃,老板没饭吃,我就自己买。

support

support的源码显示如下

	/**
	 * 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,
	 * {@code 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),

case1

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
数据库中没有任何记录

case2

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
supports传播行为可以总结老板有饭我就蹭饭,老板没饭我就绝食。一般来说supports用于查询业务。

MANDATORY

下面先来看源码

/**
	 * Support a current transaction, throw an exception if none exists.
	 * Analogous to EJB transaction attribute of the same name.
	 */
	MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

当前没有事务则直接抛出异常。

case1

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为

case2

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
MANDATORY可以总结为: 老板不给饭吃我就罢工

REQUIRES_NEW

/**
	 * 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 to it (which is server-specific in standard Java EE).
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
	REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

case1

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为

case2

mysql学习笔记(五)图解事务传播行为

mysql学习笔记(五)图解事务传播行为

mysql学习笔记(五)图解事务传播行为

case3

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
REQUIRES_NEW可以总结为: 老板给的饭太难吃,我要自己订饭,老板不给饭吃,我要自己订饭

NOT_SUPPORTED

	/**
	 * 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 to it (which is server-specific in standard Java EE).
	 * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager
	 */
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

碰到事务就挂起当前事务。

case1

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为

mysql学习笔记(五)图解事务传播行为

case2

mysql学习笔记(五)图解事务传播行为
测试结果
mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为

NOT_SUPPORTED可以总结为: 老板给的饭吃,我太忙了,没空吃饭 。

NEVER

/**
	 * Execute non-transactionally, throw an exception if a transaction exists.
	 * Analogous to EJB transaction attribute of the same name.
	 */
	NEVER(TransactionDefinition.PROPAGATION_NEVER),

case1

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为

case2

mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
mysql学习笔记(五)图解事务传播行为
NEVER则可总结为老板太难吃,逼着我罢工。

NESTED

/**
	 * Execute within a nested transaction if a current transaction exists,
	 * behave like {@code REQUIRED} otherwise. 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. Some JTA providers might support nested
	 * transactions as well.
	 * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
	 */
	NESTED(TransactionDefinition.PROPAGATION_NESTED);

case1

mysql学习笔记(五)图解事务传播行为
父事务异常影响子事务提交。
mysql学习笔记(五)图解事务传播行为
子事务异常也会影响父事务的提交。

case2

mysql学习笔记(五)图解事务传播行为
加入保存点之后,子事务就不会影响父事务的提交。
测试结果:
mysql学习笔记(五)图解事务传播行为

mysql学习笔记(五)图解事务传播行为
NESTED则可总结为老板决策不对,东家就怪罪,全部没饭吃,我就跟着受罪;我干活不对,老板马上脱罪有饭吃,害的自己受累没饭吃

总结

  • REQUIRED: 使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的;
    如果当前存在事务,则加入这个事务,成为一个整体。
  • SUPPORTS: 如果当前有事务,则使用事务;如果当前没有事务,则不使用事务。
  • MANDATORY: 该传播属性强制必须存在一个事务,如果不存在,则抛出异常
  • REQUIRES_NEW: 如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;
    如果当前没有事务,则同 REQUIRED
  • NOT_SUPPORTED: 如果当前有事务,则把事务挂起,自己不适用事务去运行数据库操作
  • NEVER: 如果当前有事务存在,则抛出异常
  • NESTED: 如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;
    如果当前没有事务,则同 REQUIRED。
    但是如果主事务提交,则会携带子事务一起提交。
    如果主事务回滚,则子事务会一起回滚。相反,子事务异常,则父事务可以回滚或不回滚。
上一篇:Cannot modify session.sql_log_bin inside a transaction


下一篇:如何确认当前事务的隔离级别?