Java面试--Spring--Spring事务传播属性详细解释

Spring的事务传播属性:

事务传播行为是Spring框架独有的事务增强特性。

1.什么是事务传播行为??

事务传播行为是用来描述由某一个事务传播行为嵌套进另一个方法时的事务如何传播。

用伪代码说明

public void methodA(){
    methodB();

}

@Transaction(Propagation = xxx)
public void methodB(){
    //do something

}

1.Required(默认属性): 

如果存在一个事务,则支持当前事务。如果没有事务,则开启一个新的事务。

2.Supports

支持当前事务,如果当前没有事务,就以非事务的方式执行

3.MANDATORY

使用当前的事务,如果没有事务,就抛出异常

4.Requires_New

新建事务,如果当前存在事务,就把当前事务挂起。

5.Not_Supported

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

6.Never

以非事务方式执行操作,如果当前存在事务,则抛出异常。

7.Nested

支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。

嵌套事务一个非常重要的概念就是内层事务依赖于外层事务,外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

代码验证

假如说我们数据库里面有两张表,user1 和user2, 列名id 和 name

连接数据库可以用mybatis或者jdbc

然后,Dao层代码:

public class User1 {
    private Integer id;
    private String name;
   //get和set方法省略...
}
public class User2 {
    private Integer id;
    private String name;
   //get和set方法省略...
}

User1Mapper:

public interface User1Mapper {
    int insert(User1 record);
    User1 selectByPrimaryKey(Integer id);
    //其他方法省略...
}

User2Mapper:

public interface User2Mapper {
  int insert(User2 record);
  User2 selectByPrimaryKey(Integer id);   //其他方法省略...
 }  

验证就在Service层实现

我们为User1Service和User2Service相应方法加上Propagation.REQUIRED属性。

User1Service方法:

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

User2Service方法:

@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();
    }
     
}

然后我们来验证:

 

@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();
}

第一种,张三,李四都会插入进去,外围方法未开启事务,插入张三 李四方法在自己的事务中独立运行,外围方法异常不影响内部。

 

@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);
}

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

 

 

结论:通过这两个方法我们证明了在外围方法未开启事务的情况下Propagation.REQUIRED修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值