ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

上一篇了解的事务的失效问题,本篇讨论事务的传播机制

2021-01-29 14:03:49  阅读:213  来源: 互联网

标签:本篇 事务 user2 user1 李四 new 失效 方法


先来几个例子描述一下spring 默认事务传播机制 Propagation.REQUIRED

@Service
public class User1ServiceImpl implements User1Service {
//省略其他…
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addRequired(User1 user){
user1Mapper.insert(user);
}
}

@Service
public class User2ServiceImpl implements User2Service {
//省略其他…
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addRequired(User2 user){
user2Mapper.insert(user);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addRequiredException(User2 user){
user2Mapper.insert(user);
throw new RuntimeException();
}

}

1.1 场景一
此场景外围方法没有开启事务。

验证方法1:

@Override
public void notransaction_exception_required_required(){
    User1 user1=new User1();
    user1.setName("张三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequired(user2);
    
    throw new RuntimeException();
}

验证方法2:

@Override
public void notransaction_required_required_exception(){
    User1 user1=new User1();
    user1.setName("张三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiredException(user2);
}

第一种 “张三”、“李四”均插入。 解析: 外围方法未开启事务,插入“张三”、“李四”方法在自己的事务中独立运行,外围方法异常不影响内部插入“张三”、“李四”方法独立的事务。

第二种: “张三”插入,“李四”未插入。 外围方法没有事务,插入“张三”、“李四”方法都在自己的事务中独立运行,所以插入“李四”方法抛出异常只会回滚插入“李四”方法,插入“张三”方法不受影响。

1.2 场景二
外围方法开启事务,这个是使用率比较高的场景。

验证方法1:

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transaction_exception_required_required(){
User1 user1=new User1();
user1.setName(“张三”);
user1Service.addRequired(user1);

    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequired(user2);
    
    throw new RuntimeException();
}

验证方法2:

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transaction_required_required_exception(){
    User1 user1=new User1();
    user1.setName("张三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiredException(user2);
}

验证方法3:

@Transactional
@Override
public void transaction_required_required_exception_try(){
    User1 user1=new User1();
    user1.setName("张三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    try {
        user2Service.addRequiredException(user2);
    } catch (Exception e) {
        System.out.println("方法回滚");
    }
}

验证方法一 “张三”、“李四”均未插入。 解析: 外围方法开启事务,内部方法加入外围方法事务,外围方法回滚,内部方法也要回滚。

验证方法二 “张三”、“李四”均未插入。 解析: 外围方法开启事务,内部方法加入外围方法事务,内部方法抛出异常回滚,外围方法感知异常致使整体事务回滚。

验证方法三 “张三”、“李四”均未插入。 解析: 外围方法开启事务,内部方法加入外围方法事务,内部方法抛出异常回滚,即使方法被catch不被外围方法感知,整个事务依然回滚。 就是try catch了也是回滚的

其他几种事务传播:

一:Propagation.REQUIRES_NEW 在外围方法未开启事务的情况下Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。 在外围方法开启事务的情况下Propagation.REQUIRES_NEW修饰的内部方法依然会单独开启独立事务,且与外部方法事务也独立,内部方法之间、内部方法和外部方法事务均相互独立,互不干扰。

二: Propagation.NESTED 在外围方法未开启事务的情况下Propagation.NESTED和Propagation.REQUIRED作用相同,修饰的内部方法都会新开启自己的事务,且开启的事务相互独立,互不干扰。 在外围方法开启事务的情况下Propagation.NESTED修饰的内部方法属于外部事务的子事务,外围主事务回滚,子事务一定回滚,而内部子事务可以单独回滚而不影响外围主事务和其他子事务

标签:本篇,事务,user2,user1,李四,new,失效,方法
来源: https://blog.csdn.net/qq_34517140/article/details/113383608

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有