zoukankan      html  css  js  c++  java
  • spring之事务的传播行为(三)

    (1)当事务被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事物,并在自己的事务中运行。

    (2)事务的传播行为可以由传播属性指定,spring定义了7种传播行为,最常用的是REQUIRED和REQUIRED_NEW。

    在上一节我们利用事务解决了购买时候的问题,本节继续介绍事务的传播行为。

    新建Cashier.java

    package com.gong.spring.tx;
    
    import java.util.List;
    
    public interface Cashier {
    
        public void checkout(String username, List<String> isbns);
        
    }

    新建CashierImpl.java

    package com.gong.spring.tx;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service("cashier")
    public class CashierImpl implements Cashier {
    
        @Autowired
        private BookShopService bookShopService;
        
        @Transactional
        @Override
        public void checkout(String username, List<String> isbns) {
            for(String isbn: isbns){
                bookShopService.purchase(username, isbn);
            }
        }
    
    }

    意思是checkout是一个添加了事务的方法,而在该方法里调用了一个也添加了事务的方法bookShopService,那么在checkout中到底是用bookShopService中的事务,还是用自己本身的事务?我们以实际结果来看。

    现在重新设置数据库中的数据:

    我们在SpringTransactionTest中测试checkout方法:

    private Cashier cashier = null;
    cashier = ctx.getBean(Cashier.class);
    @Test
    public void testTransactionlPropagation(){
        cashier.checkout("AA", Arrays.asList("1001", "1002"));
    }

    两本都是可以购买成功的:

    此时,我们再次运行SpringTransactionTest中的testTransactionlPropagation方法:

    会抛出异常:

    这是因为买了第一本之后剩30,不够买第二本,我们看看数据库中的结果:

     

    却发现一本也没有买成功,这就是事务默认的传播行为,即在现有的事务内继续运行,也就是purcase方法上的注解实际默认是@Transactional(propagation=Propagation.REQUIRED)。因此checkout和bookShopService自始至终都在一个事务中,这个事务只在checkout结束的时候被提交,因此用户一本书都买不到。

    使用@Transactional(propagation=Propagation.REQUIRES_NEW)来表示方法新开一个事务,如果该方法被另一个事务方法所调用,那么调用的事务方法就暂时被挂起。也就是说,为purchase方法加上了@Transactional(propagation=Propagation.REQUIRES_NEW)之后,purchase会在自己的事务中运行,并且在运行完之后,再运行checkout的事务。

    我们为purchase上加上@Transactional(propagation=Propagation.REQUIRES_NEW)注解,再看下结果:

    可以成功的买到一本。 

  • 相关阅读:
    Kubernetes-Pod的扩、缩容以及滚动升级
    从一个例子开始认识Kubernetes
    Kubernetes的基本术语和概念
    一分钟看懂Docker的网络模式和跨主机通信
    监控神器:Premotheus+Grafana安装
    Linux不同服务器之间copy文件
    Oracle 存储情况查询
    Kubernetes v1.10 快速安装(只需三步)
    django 搭建一个投票类网站(二)
    django 搭建一个投票类网站(一)
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12168593.html
Copyright © 2011-2022 走看看