Spring事务传播行为
Posted 荠菜煎包
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring事务传播行为相关的知识,希望对你有一定的参考价值。
Spring事务传播行为有7种:
spring的7种传播行为:
1.required:(默认传播行为),如果当前有事务,其他就用当前事务,不会新增事务。
例如:方法A调用方法B,它们用同一个事务。(如果B没有事务,它们会用同一个事务。)(只要有一个回滚,整体就会回滚)
2.requires_new:如果当前有事务,其他不会加入当前事务,会新增事务。即他们的事务没有关系,不是同一个事务。
如果其他没有事务,那么以当前事务运行。
例如:方法A调用方法B,它们用不同的事务。(B不会用A的事务,会新增事务。)
3.supports:当前没有事务,就以非事务运行。当前有事务呢?就以当前事务运行。
例如:方法A调用方法B,如果A没有事务,那么B就以非事务运行。
如果A有事务就以A事务为准。如果A没有事务,那么B就会以非事务执行。
4.mandatory:其他没有事务就会抛异常。当前没有事务抛出异常,当前有事务则支持当前事务。
支持当前事务,如果当前没有事务就会抛出异常。
例如:方法A调用方法B,如果方法A没有事务,那么就会抛出异常。
5.not_supported:以非事务执行。
例如:方法A调用方法B,方法B会挂起事务A以非事务方式执行。
6.never:以非事务执行,如果存在事务,抛出异常。
总是以非事务执行,如果存在事务,那么就抛出异常。
7.nested:如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。
如果当前事务不存在,那么其行为与Required一样。
例如:方法A中调用了方法B,B中try catch手动回滚,A不会回滚。
======================================
1.required:(默认传播行为),如果当前有事务,其他就用当前事务,不会新增事务。
例如:方法A调用方法B,它们用同一个事务。(如果B没有事务,它们会用同一个事务。)(只要有一个回滚,整体就会回滚)
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest();
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addTest() testDao.addTest(); int i = 1/0;
REQUIRED表示在同一个事务: 1.addTest异常会使得整个事务回滚,user表和test表都没插入成功。 2.addUser异常也会使得事务回滚,user表和test表都没插入成功。
2.requires_new:如果当前有事务,其他不会加入当前事务,会新增事务。即他们的事务没有关系,不是同一个事务。
如果其他没有事务,那么以当前事务运行。
例如:方法A调用方法B,它们用不同的事务。(B不会用A的事务,会新增事务。)
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest();
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); int i = 1/0; catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
REQUIRES_NEW表示addTest新创建了一个事务,跟addUser不在同一个事务里。两个事务互不影响。 1.addTest异常,进行回滚。addUser没有回滚。user表插入成功,test表插入失败。 2.addUser异常,进行回滚。addTest没有回滚。test表插入成功,user表插入失败。
3.supports:当前没有事务,就以非事务运行。当前有事务呢?就以当前事务运行。
例如:方法A调用方法B,如果A没有事务,那么B就以非事务运行。
如果A有事务就以A事务为准。如果A没有事务,那么B就会以非事务执行。
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest(); int i = 1/0;
@Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
如果addUser有事务,那么addTest跟addUser在同一个事务。如果addUser没有事务,那么就以非事务方式运行。
4.mandatory:其他没有事务就会抛异常。当前没有事务抛出异常,当前有事务则支持当前事务。
支持当前事务,如果当前没有事务就会抛出异常。
例如:方法A调用方法B,如果方法A没有事务,那么就会抛出异常。
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest(); int i = 1/0;
@Transactional(propagation = Propagation.MANDATORY,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
如果addUser有事务,那么addTest跟addUser在同一个事务。如果addUser没有事务,那么就会报异常:No existing transaction found for transaction marked with propagation 'mandatory'
5.not_supported:以非事务执行。
例如:方法A调用方法B,方法B会挂起事务A以非事务方式执行。
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest(); int i = 1/0;
@Transactional(propagation = Propagation.NOT_SUPPORTED,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
如果addUser异常,会回滚。addTest不会滚。不管addUser是否有事务,addTest都以非事务方式运行。
6.never:以非事务执行,如果存在事务,抛出异常。
总是以非事务执行,如果存在事务,那么就抛出异常。
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest(); int i = 1/0;
@Transactional(propagation = Propagation.NEVER,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
如果addUser没有事务,addTest以非事务方式运行。如果addUser有事务,addTest就会报错:Existing transaction found for transaction marked with propagation 'never'
never和mandatory正好相反。
7.nested:如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。
如果当前事务不存在,那么其行为与Required一样。
例如:方法A中调用了方法B,B中try catch手动回滚,A不会回滚。
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class) public void addUser() userDao.addUser(); testService.addTest();
@Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class) public void addTest() try testDao.addTest(); int i = 1/0; catch (Exception e) TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
addUser的事务内嵌addTest的事务,如果addUser异常回滚,那么addTest也会回滚。如果addTest回滚,addUser不会回滚。
nested和requires_new的不同是:
nested内层事务回滚不影响外层,外层事务回滚影响内层跟着回滚。
requires_new外层和内层不是同一个事务,互不影响。外层回滚不影响内层,内层回滚不影响外层。
以上是关于Spring事务传播行为的主要内容,如果未能解决你的问题,请参考以下文章