Spring的七个事务传播行为
Spring事务种类
Spring事务含有七个级别,分别如下:
REQUIRED
REQUIRED是Spring的默认事务级别,如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务,具体表现在方法上加入注解@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED),以下几个级别相同。
SUPPORTS
如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,SUPPORTS与不使用事务有少许不同。
MANDATORY
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
NOT_SUPPORTED
总是非事务地执行,并挂起任何存在的事务。
NEVER
总是非事务地执行,如果存在一个活动事务,则抛出异常
NESTED
如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按REQUIRED 属性执行
数据验证
调用方法A事务 | 被调用方法B事务 | A方法是否捕获B方法 | 调用方法A抛出异常 | 被调用方法B抛出异常 | 调用方法数据是否入库 | 被调用方法数据是否入库 | 结论 | REQUIRED | REQUIRED | 否 | 否 | 是 | 否 | 否 | 两个方法在同一个事务中,如果上下文有事务则加入其中,如果没有则创建新事务。 | REQUIRED | REQUIRED | 是 | 否 | 是 | 否 | 否 | REQUIRED | SUPPORTS | 否 | 否 | 是 | 否 | 否 | 当上下文有事务时,则加入事务中,如果没有事务则执行无事务操作, 即时被调用方法出错了也不会有回滚操作 | NEVER | SUPPORTS | 否 | 否 | 是 | 是 | 是 | REQUIRED | MANDATORY | 否 | 否 | 是 | 否 | 否 | 报No existing transaction found for transaction marked with propagation 'mandatory'错误,说明MANDATORY上下文中有事务时则加入其中,如果没有则直接报上述错误 | NEVER | MANDATORY | 否 | 否 | 否 | 是 | 否 | REQUIRED | REQUIRES_NEW | 否 | 否 | 是 | 否 | 否 | REQUIRES_NEW每次都要一个新事务,如果子事务抛出异常并且父事务捕获了子事务异常,则父事务不回滚,否则两者都要回滚;如果父事务调用子事务后父事务抛出异常,则子事务不回滚,而父事务回滚。 | REQUIRED | REQUIRES_NEW | 是 | 否 | 是 | 是 | 否 | REQUIRED | REQUIRES_NEW | 否 | 是 | 否 | 否 | 是 | REQUIRED | NOT_SUPPORTED | 否 | 否 | 是 | 否 | 是 | 定义了NOT_SUPPORTED事务的方法,不管自己是否出错都会提交事务,调用方法A如果调用了方法B,并且捕获了B的异常,则方法A会提交事务,否则回滚事务。 | REQUIRED | NOT_SUPPORTED | 否 | 是 | 否 | 否 | 是 | REQUIRED | NOT_SUPPORTED | 是 | 否 | 是 | 是 | 是 | REQUIRED | NEVER | 否 | 否 | 否 | 否 | 否 | 直接报“ Existing transaction found for transaction marked with propagation 'never'”异常 | REQUIRED | NESTED | 否 | 否 | 是 | 否 | 否 | NESTED,嵌套事务,如果子事务发生异常,并且父事务对子事务进行了异常捕获,则子事务回滚,父事务不回滚,否则都要回滚;只要父事务发生异常,父事务子事务都回滚,这个与REQUIRES_NEW不一样; | REQUIRED | NESTED | 是 | 否 | 是 | 是 | 否 | REQUIRED | NESTED | 否 | 是 | 否 | 否 | 否 | |
也可参考http://blog.csdn.net/linuu/article/details/51006780