美文网首页
spring_aop propagetion 之 REQUIRE

spring_aop propagetion 之 REQUIRE

作者: _PatrickStar | 来源:发表于2021-03-27 13:39 被阅读0次

    小白菜,刚学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 之 REQUIRE

          本文链接:https://www.haomeiwen.com/subject/oezehltx.html