spring_aop propagetion 之 REQUIRED,REQUIRES_NEW,NESTED区别

小白菜,刚学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的不行,就这点区别。

你可能感兴趣的:(spring_aop propagetion 之 REQUIRED,REQUIRES_NEW,NESTED区别)