首页 > 数据库 >Spring 事务(测试)--在这个笔记中记录的是没有添加事务,数据库返回的效果。

Spring 事务(测试)--在这个笔记中记录的是没有添加事务,数据库返回的效果。

时间:2022-11-12 22:34:04浏览次数:45  
标签:事务 service -- Spring goodsId com import bjpowernode public

第5章Spring 事务(测试)--在这个笔记中记录的是没有添加事务,数据库返回的效果。

1. 首先搞两张表,商品表和订单表

举例:购买商品 trans_sale 项目 本例要实现购买商品,模拟用户下订单,向订单表添加销售记录,从商品表减少库存。

实现步骤:

  • Step0:创建数据库表

    sale 销售表

    goods 商品表

  • Step1: maven 依赖 pom.xml

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.5.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.1</version>
    </dependency>
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
    </dependency>
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
    </dependency>
    插件
    <build>
     <resources>
     <resource>
     <directory>src/main/java</directory><!--所在的目录-->
     <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
     <include>**/*.properties</include>
     <include>**/*.xml</include>
     </includes>
     <filtering>false</filtering>
     </resource>
      </resources>
     <plugins>
     <plugin>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>3.1</version>
     <configuration>
     <source>1.8</source>
     <target>1.8</target>
     </configuration>
     </plugin>
     </plugins>
    </build>
    

    项目的结构

  • Step2:创建实体类

    创建实体类 Sale 与 Goods

  • Step3:定义 dao 接口

  • Step4:定义 dao 接口对应的 sql 映射文件

  • Step5:定义异常类

    定义 service 层可能会抛出的异常类 NotEnoughException

    package com.bjpowernode.excep;
    
    //自定义的运行时异常
    public class NotEnoughException extends RuntimeException {
        public NotEnoughException() {
            super();
        }
    
        public NotEnoughException(String message) {
            super(message);
        }
    }
    
  • Step6:定义 Service 接口

    package com.bjpowernode.service;
    
    public interface BuyGoodsService {
    
        //购买商品的方法, goodsId:购买商品的编号, nums:购买的数量
        void buy(Integer goodsId,Integer nums);
    }
    
  • Step7:定义 service 的实现类

    package com.bjpowernode.service.impl;
    
    import com.bjpowernode.dao.GoodsDao;
    import com.bjpowernode.dao.SaleDao;
    import com.bjpowernode.domain.Goods;
    import com.bjpowernode.domain.Sale;
    import com.bjpowernode.excep.NotEnoughException;
    import com.bjpowernode.service.BuyGoodsService;
    
    public class BuyGoodsServiceImpl implements BuyGoodsService {
    
        private SaleDao saleDao;
        private GoodsDao goodsDao;
        @Override
        public void buy(Integer goodsId, Integer nums) {
            System.out.println("=====buy方法的开始====");
            //记录销售信息,向sale表添加记录
            Sale sale  = new Sale();
            sale.setGid(goodsId);
            sale.setNums(nums);
            saleDao.insertSale(sale);
    
            //更新库存
            Goods goods  = goodsDao.selectGoods(goodsId);
            if( goods == null){
                //商品不存在
                throw  new  NullPointerException("编号是:"+goodsId+",商品不存在");
            } else if( goods.getAmount() < nums){
                //商品库存不足
                throw new NotEnoughException("编号是:"+goodsId+",商品库存不足");
            }
            //修改库存了
            Goods buyGoods = new Goods();
            buyGoods.setId( goodsId);
            buyGoods.setAmount(nums);
            goodsDao.updateGoods(buyGoods);
            System.out.println("=====buy方法的完成====");
        }
    
    
        public void setSaleDao(SaleDao saleDao) {
            this.saleDao = saleDao;
        }
    
        public void setGoodsDao(GoodsDao goodsDao) {
            this.goodsDao = goodsDao;
        }
    }
    
  • Step8:修改 Spring 配置文件内容

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--
           把数据库的配置信息,写在一个独立的文件,编译修改数据库的配置内容
           spring知道jdbc.properties文件的位置
        -->
        <context:property-placeholder location="classpath:jdbc.properties" />
    
        <!--声明数据源DataSource, 作用是连接数据库的-->
        <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
              init-method="init" destroy-method="close">
            <!--set注入给DruidDataSource提供连接数据库信息 -->
            <!--    使用属性配置文件中的数据,语法 ${key} -->
            <property name="url" value="${jdbc.url}" /><!--setUrl()-->
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.passwd}" />
            <property name="maxActive" value="${jdbc.max}" />
        </bean>
    
        <!--声明的是mybatis中提供的SqlSessionFactoryBean类,这个类内部创建SqlSessionFactory的
            SqlSessionFactory  sqlSessionFactory = new ..
        -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!--set注入,把数据库连接池付给了dataSource属性-->
            <property name="dataSource" ref="myDataSource" />
            <!--mybatis主配置文件的位置
               configLocation属性是Resource类型,读取配置文件
               它的赋值,使用value,指定文件的路径,使用classpath:表示文件的位置
            -->
            <property name="configLocation" value="classpath:mybatis.xml" />
        </bean>
    
        <!--创建dao对象,使用SqlSession的getMapper(StudentDao.class)
            MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象。
    
        -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!--指定SqlSessionFactory对象的id-->
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
            <!--指定包名, 包名是dao接口所在的包名。
                MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行
                一次getMapper()方法,得到每个接口的dao对象。
                创建好的dao对象放入到spring的容器中的。 dao对象的默认名称是 接口名首字母小写
            -->
            <property name="basePackage" value="com.bjpowernode.dao"/>
        </bean>
    
        <!--声明service-->
        <bean id="buyService" class="com.bjpowernode.service.impl.BuyGoodsServiceImpl">
            <property name="goodsDao" ref="goodsDao" />
            <property name="saleDao" ref="saleDao" />
        </bean>
    
    </beans>
    
  • 其中mybatis的主配置文件和jdbc连接的配置文件如下:

  • Step9:定义测试类

    package com.bjpowernode;
    
    import com.bjpowernode.service.BuyGoodsService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
    
        @Test
        public void test01(){
            String config="applicationContext.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
            //从容器获取service
            BuyGoodsService service = (BuyGoodsService) ctx.getBean("buyService");
    
            //调用方法
            service.buy(1001,200);
        }
    
    }
    
  • 当正常执行时候。

  • 商品不存在时

  • 商品数量不足时候

标签:事务,service,--,Spring,goodsId,com,import,bjpowernode,public
From: https://www.cnblogs.com/atao-BigData/p/16884892.html

相关文章

  • Oracle 19C学习 - 22. WITH AS 语句
    什么是WITHAS语句WITHAS相当于虚拟视图。WITHAS也叫做分解子查询或者片段子查询。定义一个SQL片段,该片段会被后面的SQL语句用到,可以近似看作一个可用的临时视图。......
  • 单细胞分析:归一化和回归(八)
    导读现在有了高质量的细胞,首先探索数据并确定任何不需要的变异来源。然后需要对数据进行归一化,计算方差并回归任何对数据有影响的协变量。1.学习目标学会如何执行归一......
  • Python_解决脚本执行过程中,文件被多次读取的问题
    今天在封装pandas过程中,发现封装脚本的执行耗时明显高于未封装的脚本复盘问题importtimeclassDemo:defmock_read_excel(self):print("读取文件")......
  • (作者推荐)【RocketMQ入门到精通】— RocketMQ中级特性能力 | ​长轮询Pull和Push模式
    名言警句任何先进的技术均与魔法无异追本溯源【​​经历了6个月的失踪,我将带着干货终究归来!【RocketMQ入门到精通】​​】RocketMQ消费机制回顾   在众多MQ的体系中,一......
  • 第五章 RBAC访问控制
    Role-BasedAccessControl,基于角色的访问控制,apiserver启动参数添加--authorization-mode=RBAC来启用RBAC认证模式,kubeadm安装的集群默认已开启。​​官方介绍​​查看开......
  • 补档--【THM】Content Discovery(网站内容发现)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/contentdiscovery通过学习相关知识点:了解在网络服务器上发现可能导致漏洞的隐藏或私人内容的各种方法(网站内......
  • Hive3源码总结2
    大数据技术之Hive源码2接上文2.4HQL生成AST(抽象语法树)2.5对AST进一步解析 接下来的步骤包括:1)将AST转换为QueryBlock进一步转换为OperatorTree;2)对OperatorTree进行逻辑优......
  • Docker的介绍与安装
    Docker是什么Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实......
  • 卡巴斯基发布2016年2季度DDoS报告:Linux僵尸网络“挑大梁”
     据外媒报道,Linux僵尸网络已占2016年2季度发起的“分布式拒绝服务攻击”(DDoS)中的70.2%。过去三个月时间里,安全研究人员发掘出了运行基于Linux的固件、能够发起DDoS攻击、......
  • EXC_RETURN
    当任务启动或切换的SVC中断结束时,返回一个在r14的特殊值---EXC_RETURN,其决定返回后系统进入什么模式:1.线程模式orHandler模式;2.出栈操作的SP指向哪个栈:PSPorMSP。......