本篇博文小猿主要是针对事务的应用,而事务的传播行为有7类,这7种传播行为各有不同的应用场景,以下小猿将论述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),
上述图中最后一句写的不好,应该是两个children方法执行保存失败,而不是不执行。
上述图中虽然在函数2中添加了事务,但应为函数1中已经有事务,而传播行为required,这说明当执行函数2时,看到函数1已经存在时候,则直接加入函数1的事务,自己就不再创建新事务,这种现象就是required事务的传播,此时无论函数是否有事务注解都无关紧要,子事务都会加入到父事务中, 按照事务的原子性,此时采用函数1的事务,则中间如果出现一次异常,这此次事务全部执行失败。
完全回滚。
require传播行为可以总结为老板有饭吃,我就蹭饭吃,老板没饭吃,我就自己买。
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),
数据库中没有任何记录
supports传播行为可以总结老板有饭我就蹭饭,老板没饭我就绝食。一般来说supports用于查询业务。
下面先来看源码
/** * Support a current transaction, throw an exception if none exists. * Analogous to EJB transaction attribute of the same name. */ MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
当前没有事务则直接抛出异常。
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 to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
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 to it (which is server-specific in standard Java EE). * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
碰到事务就挂起当前事务。
测试结果
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),
NEVER则可总结为老板太难吃,逼着我罢工。
/** * 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);
父事务异常影响子事务提交。
子事务异常也会影响父事务的提交。
加入保存点之后,子事务就不会影响父事务的提交。
测试结果:
NESTED则可总结为老板决策不对,东家就怪罪,全部没饭吃,我就跟着受罪;我干活不对,老板马上脱罪有饭吃,害的自己受累没饭吃