在Spring中,事务传播机制是一个重要的概念,它决定了一个新事务是如何与已有事务交互的。如果没有正确地处理事务传播机制,会导致应用程序中的错误以及数据一致性问题。
REQUIRED(required)(必须的,默认)
如果当前存在事务,则加入该事务,如果不存在事务,则创建一个事务。
解释:当方法a声明了该事务,方法b也声明该事务时,如果方法a调用了方法b,那么b不会再创建自己事务而是加入方法a,他们共享同一个事务上下文,b回滚a也回滚、a回滚b也回滚。而当方法a未声明事务,方法b声明了该事务时,a调用b,会为方法b创建事务,而a不会。
SUPPORTS(supports)(支持的)
如果当前存在事务,则加入该事务,如果不存在事务,则以非事务的方式执行。
解释:当方法a声明了一个事务,方法b声明了该事务时,同理,他们共享事务上下文。而当方法a未声明事务,方法b声明该事务,a调用b,a、b都没有事务,出现异常时a、b都不回滚。当然如果有一个方法c声明了该事务,我们直接调用该方法,出现异常也不会回滚,因为主方法是未声明事务的因此c也以非事务的方式执行。
MANDATORY(mandatory)(强制的)
如果当前存在事务,则加入到当前事务中;如果当前没有事务,则抛出异常。
解释:当方法a声明了一个事务,方法b声明了该事务时,同理,他们共享事务上下文。而当方法a未声明事务,方法b声明该事务,a调用b,抛出异常。同理如果有一个方法c声明了该事务,我们直接调用该方法,由于主方法未声明事务因此会直接抛出异常。
REQUIRES_NEW(requires_new)(需要新的)
总是创建一个新的事务,如果当前存在事务,则挂起当前事务。
解释:不论方法a是否声明事务,方法b声明了该事务时,a调用b,都会为b创建一个自己的事务。而当a没有事务时,b独立事务运行;当a有事务时,挂起a的事务,等待b的事务执行完毕后再恢复执行a。
NOT_SUPPORTED(not_supported)(不支持)
以非事务方式执行操作,如果当前存在事务,则挂起当前事务。
解释:如果方法a存在事务,会挂起a的事务,等待b执行完毕后再恢复执行a。
NEVER(绝不)
以非事务方式执行操作,如果当前存在事务,则抛出异常。
解释:当方法a声明了一个事务,方法b声明了该事务时,a调用b,b方法会抛出异常。
NESTED(嵌套的)
如果当前存在事务,则在当前事务中创建一个新的嵌套事务;如果当前没有事务,则创建一个新的事务。
解释:如果数据库支持嵌套事务,那么就会存在多个begin和commit,a调用b,方法b运行完就提交了,与a互不影响。如果数据库不支持嵌套事务比如常用的MySQL,那么使用savepoint设置保存点,如果代码出现问题需要回滚,就使用rollback返回到保持点,最后在代码执行完后commit。