Spring事务有7种传播属性:
1.PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
2.PROPAGATION_SUPPORTS:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
3.PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
4.PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。
下面,我们以PROPAGATION_REQUIRED和PROPAGATION_REQUIRES_NEW来写一个示例:
@Transactional
@Override
public void addUser() {
User user1 = new User();
user1.setUserName("zhaoliu21");
user1.setName("赵柳21");
user1.setPassword("12323");
user1.setSex(1);
user1.setUserType(12);
user1.setStatus(1);
user1.setOrganizationId(12);
userMapper.insert(user1);
try {
((UserService)AopContext.currentProxy()).updateUser(user1);
}catch (Exception e) {
System.out.println("ArithmeticException****************************");
e.printStackTrace();
}
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public void updateUser(User user) {
System.out.println("************updateUser 开始**************");
User user1 = new User();
user1.setId(46L);
user1.setName("王武");
userMapper.updateUserById(user1);
System.out.println("************updateUser 结束**************");
int a = 1/0;
}
当调用updateUser()时,会重新开启一个事务,由于程序执行1/0会报异常,要保证内部事务回滚,外部事务正常提交,那么就要在addUser()中调用updateUser()时进行try{}catch () {}处理。
@Transactional
@Override
public void addUser() {
User user1 = new User();
user1.setUserName("zhaoliu21");
user1.setName("赵柳21");
user1.setPassword("12323");
user1.setSex(1);
user1.setUserType(12);
user1.setStatus(1);
user1.setOrganizationId(12);
userMapper.insert(user1);
((UserService)AopContext.currentProxy()).updateUser(user1);
int a = 1/0;
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public void updateUser(User user) {
System.out.println("************updateUser 开始**************");
User user1 = new User();
user1.setId(46L);
user1.setName("王武");
userMapper.updateUserById(user1);
System.out.println("************updateUser 结束**************");
}
如上代码,当addUser()程序异常时,外部事务回滚,内部事务会正常提交。
void methodA(){
service.methodB();
}
void methodB(){
}
这里有A,B两个方法,在A方法中调用B方法。分如下两种情况:
一、运行的B方法出现异常
1.不做处理
新建事务:影响外部事务,影响自己
嵌套事务:影响外部事务,影响自己
共享事务:影响外部事务,影响自己
2.B方法抛出异常,由A方法内部处理
新建事务:不影响外部事务,影响自己
嵌套事务:不影响外部事务,影响自己
共享事务:影响外部事务,影响自己
3.B方法内部处理
不影响任何事务
4.两个方法都抛异常
等同不做处理
二、运行的A方法出现异常,B方法不出现异常
1.不做处理
新建事务:影响自己,不影响内部事务
嵌套事务:影响自己,影响内部事务
共享事务:影响自己,影响内部事务
2.A方法内部处理
新建事务:全部不影响
嵌套事务:全部不影响
共享事务:全部不影响
3.A方法抛异常
等同不做处理
腾讯云618大促:腾讯云618钜惠
阿里云最高2000代金券:阿里云新购、续费、升级优惠券