Spring事务的传播级别
required: 如果当前有事务就使用当前事务, 如果没有就新建一个事务(default)
requires_new: 无论有没有事务,总是新建一个事务
nested: 和required类似, 不同点在于会设置一个还原点, 如果出问题只会还原本方法, 并不会还原外部方法。
supports: 支持当前事务, 如果当前没有事务, 就以非事务的方式执行
not_supported: 以非事务的方式执行, 如果当前存在事务就挂起
never: 总是在非事务下执行, 如果有事务就报错
mandatory: 总是在事务下执行,如果没有事务就报错
------------------------------------------------------------------------------具体实例---------------------------------------------------------------------------------------------
REQUIRED
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void b(){ //crud... }
a()调用b()的情况下:a()会开启一个事务, 然后b()会继续使用a()的事务。
单独调用b():b()就会新开启一个事务。无论是哪个一个报错(抛异常), before() b() after()这三个都会回滚。
如果嵌套执行的方法要求一起执行成功或者一起回滚,则选择该事物传播级别。
REQUIRES_NEW
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) void b(){ //crud... }
a()调用b()的情况下:a()会开启一个事务, 然后b()不会继续使用a()的事务,会单独开启一个事务。如果b()报错了,只会回滚b(),不会影响before()。after()报错了也不会影响b()。
如果嵌套执行的方法要求各自事务独立,不能进行相互影响,则选择本事务传播级别。
NESTED
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED) void b(){ //crud... }
a()调用b()的情况下:a()会开启一个事务, 然后b()会继续使用a()的事务。但是b()会设置一个还原点, 当b()报错了,只会回滚b()自已,不会回滚before()。如果after()报错了这三个都会回滚。
可以使用以下代码设置保存点 和 回滚到时指定的保存点
//设置保存点 Object savepoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); //回滚到指定的保存点 TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savepoint); //如果需要在catch块中做一些其他操作, 这时方法不可以抛出异常,则可以在catch块中加入这行代码用来替代throws Exception TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
如果嵌套执行的方法要求内部方法出错只回滚自己,外部方法执行失败回滚所有,单独执行时候自动开启一个执行,则选择该事物传播级别。
MANDATORY
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY) void b(){ //crud... }
a()调用b()的情况下:和REQUIRED一样。
单独调用b():报错。
如果嵌套执行的方法要求一起执行成功或者一起回滚,单独执行时候不允许以非事务方式执行,则选择该事物传播级别。
NEVER
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.NEVER) void b(){ //crud... }
a()调用b()的情况下:报错。
单独调用b():不开启事务。
如果嵌套执行的方法要求内部方法不允许在事务中执行,单独执行时候必须以非事务方式执行,则选择该事物传播级别。
SUPPORTS
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.SUPPORTS) void b(){ //crud... }
a()调用b()的情况下:和REQUIRED一样。
单独调用b():不开启事务。
如果嵌套执行的方法要求一起执行成功或者一起回滚,单独执行时候以非事务方式执行,则选择该事物传播级别。
NOT_SUPPORTED
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) void a(){ before(); b(); after(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.NOT_SUPPORTED) void b(){ //crud... }
a()调用b()的情况下:挂起a()的事务,不在事务的情况下b(),after()也无法影响b()。
单独调用b():不开启事务。
如果嵌套执行的方法要求内部嵌套方法不会对外部方法事务造成影响并且内部方法不需要事务,单独执行时候以非事务方式执行,则选择该事物传播级别。