什么是事务的传播属性
举个栗子:在上一个笔记中我们用到了转账的栗子,使用到了事务,这时有了新的需求,要求能够批量转账。要实现这个功能很简单,写一个批量转账的方法batTransfer,for循环转账即可。
问题来了:批量转账这个方法肯定也是要用事务的,那么它是使用转账方法transfer()的事务呢还是batTransfer()自己重新开一个事务?这就是事务的传播属性
关于转账的栗子,请参考:spring学习笔记(21)——声明式事务
默认传播属性
- 写一个批量转账,我们进行两次转账,一次转100块
batService.batTransfer("tom", "jack", 100);
//转账
@Transactional
public void transfer(String from,String to,int money) throws RuntimeException{
System.out.println("转账----------");
this.income(to, money);
this.outcome(from, money);
}
package com.sm.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class BatService {
@Autowired
private UserService userService;
//批量转账
@Transactional
public void batTransfer(String from,String to,int money){
//转账
userService.transfer(from, to, money);
//再次转账
userService.transfer(from, to, money);
};
}
- 先看余额
从余额上看,第一次转账可以成功,第二次转账时,将抛出余额不足的异常
- 运行看看
- 从截图看很容易发现,确实转账了两次,并且第二次发生了余额不足的异常,但是查看数据库,发现一次转账都没有成功,这就是事务的默认传播属性:
@Transactional(propagation=Propagation.REQUIRED)
- 事务默认传播属性,只使用一个事务
Propagation.REQUIRES_NEW
这是另一种传播属性
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void transfer(String from,String to,int money) throws RuntimeException{
System.out.println("转账----------");
this.income(to, money);
this.outcome(from, money);
}
- 我们来运行看看
可以看到,第一次转账成功了,这就是REQUIRES_NEW
注意
- REQUIRES_NEW是加载被调用的方法上
- 批量转账和转账两个方法必须在不同的类中REQUIRES_NEW才有效