小白菜,刚学spring aop的事务传播特性,比较重要的三个REQUIRED,REQUIRES_NEW,NESTED自己的理解,发出来自己可以时常看看,也欢迎指正!
贴一些核心代码,两个实现类,
不用关心内部实现,只要将关注点放在Propagation上
@Repository
public class BookService {
@Autowired
BookDao bookDao;
@Transactional(propagation = Propagation.REQUIRED)
public void buyBook(String username,int id){
int price = bookDao.getPrice(id);
String bookname = bookDao.getBookName(id);
bookDao.updateBalance(username,price);
bookDao.updateStock(id);
// int i=1/0;
System.out.println(username+" 花了"+price+"元,买了一本"+bookname);
}
@Transactional(propagation = Propagation.REQUIRED)
public void updatePrice(int id){
String bookname = bookDao.getBookName(id);
bookDao.updatePrice(id);
int price = bookDao.getPrice(id);
// int i= 1/0;
System.out.println(bookname+"现价:"+price);
}
}
@Service
public class MultService {
@Autowired
BookService bookService;
@Transactional
public void mult(){
bookService.buyBook("zhangsan",1);
bookService.updatePrice(1);
int i=1/0;
}
}
可以看出MultService里面是调用了BookService 的,我们将BookService 视为内部,MultService视为外部
结构如图
@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.NESTED)
主要说明上面三种情况
1、事务传播级别是REQUIRED,当buyBook()被调用时(假定被另一类中commit()调用),如果buyBook()中的代码抛出异常,即便被捕获,commit()中的其他代码都会roll back,相当于只要任何一个有异常,无论是自己还是别人,最终都会回滚(因为最外层还嵌套了一层事务)。
2.png
2、是REQUIRES_NEW,如果buyBook()中的代码抛出异常,并且被捕获,commit()中的其他代码不会roll back;如果commit()中的其他代码抛出异常,而且没有捕获,不会导致buyBook()回滚,可以想象成加了REQUIRES_NEW就等于自己是一个相对独立的事务,我自己有异常,我就会回滚,我没异常,别人有异常也不会影响我提交。
3.png
3、是NESTED,如果buyBook()中的代码抛出异常,并且被捕获,commit()中的其他代码不会roll back;如果commit()中的其他代码抛出异常,而且没有捕获,会导致buyBook()回滚,简单理解如果内层方法都正常,但是外层出了异常,(看外层方法加了个1/0会导致异常,分母不能为0。)最后还是会导致全部回滚。
public void mult(){
bookService.buyBook("zhangsan",1);
bookService.updatePrice(1);
int i=1/0;
}
4.png
最后再提一点REQUIRES_NEW和NESTED在外层都有异常时候的区别在于有REQUIRES_NEW注解的方法块如果正常运行,是可以直接commit的,但是NESTED的不行,就这点区别。
网友评论