• Spring事务 注解模式(购物等例子适用)


      自从有了基于aop的事务注解,事务的使用变得更简单,相信大家都喜欢这货。够轻、够好用,哪里需要事务只需要一个注解即可,可以在类或者是方法上使用它。

    流程如下:
    ①查询上平(通过id)得到上平的价格
    ②选择商品(通过id)将商品数量减一
    ③用户余额修改(用户名)余额减去商品的价格
    要注意的是,用户余额不足的时候不能购买商品,商品数量不足的时候用户也不能购买商品
     
    程序需要的jar包:

      aopalliance.jar
      aspectjweaver.jar
      c3p0-0.9.2.1.jar
      commons-codec-1.10.jar
      commons-logging.jar
      mchange-commons-java-0.2.3.4.jar
      mysql-connector-java-5.1.7-bin.jar
      spring-aop-4.2.0.RELEASE.jar
      spring-aspects-4.2.0.RELEASE.jar
      spring-beans-4.2.0.RELEASE.jar
      spring-context-4.2.0.RELEASE.jar
      spring-core-4.2.0.RELEASE.jar
      spring-expression-4.2.0.RELEASE.jar
      spring-jdbc-4.2.0.RELEASE.jar
      spring-tx-4.2.0.RELEASE.jar、

    GoodDao.java

    package com.qb.spring.tx;
    
    public interface GoodDao {
        //查找商品价格
        public int findPriceById(String id);
        
        //修改商品数量每次-1
        public void updateGoods(String id);
        
        //修改用户的余额
        public void updateBalance(String username,int price);
    }

    GoodDaoImpl.java

    package com.qb.spring.tx;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    import com.qb.spring.tx.GoodsException;
    import com.qb.spring.tx.UserException;
    //声明并配置到Spring中 @Repository(
    "goodDao") public class GoodDaoImpl implements GoodDao {
    //配置属性自动 @Autowired
    private JdbcTemplate jdbcTemplate; @Override public int findPriceById(String id) { String sql = "select price from goods where id=?";
    //        返回值为Integer的类类型
    return jdbcTemplate.queryForObject(sql, Integer.class, id); } @Override public void updateGoods(String id) { String sql2 = "select number from good_numbers where id = ?"; int number = jdbcTemplate.queryForObject(sql2, Integer.class, id); if(number<0){
    //      该异常为自定义异常,仅继承了 RunTimeException
    throw new GoodsException("商品数量不足"); } String sql="update good_numbers set number=number-1 where id=?"; jdbcTemplate.update(sql, id); } @Override public void updateBalance(String username, int price) { String sql2 = "select balance from users where username=?"; int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username); if(balance-price<0){ throw new UserException("用户余额不足"); } String sql = "update users set balance=balance-? where username=?"; jdbcTemplate.update(sql, price,username); } }

    GoodService.java

    package com.qb.spring.tx;
    
    public interface GoodService {
        public void buyGoods(String username,String id);
    }

    GoodServiceImpl.java

    package com.qb.spring.tx;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    
    @Service("goodService")
    public class GoodServiceImpl implements GoodService {
        @Autowired
        private GoodDao goodDao;
        @Transactional
        @Override
        public void buyGoods(String username,String id) {
            int price = goodDao.findPriceById(id);
            goodDao.updateGoods(id);
            goodDao.updateBalance(username, price);
    
        }
    
    }

    GoodException.java

    package com.qb.spring.tx;
    
    public class GoodsException extends RuntimeException{
    
        public GoodsException() {
            super();
        }
    
        public GoodsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }
    
        public GoodsException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public GoodsException(String message) {
            super(message);
        }
    
        public GoodsException(Throwable cause) {
            super(cause);
        }
        
    }

    UserException.java

    package com.qb.spring.tx;
    
    public class UserException extends RuntimeException{
    
        public UserException() {
            super();
        }
    
        public UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }
    
        public UserException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public UserException(String message) {
            super(message);
        }
    
        public UserException(Throwable cause) {
            super(cause);
        }
    
    }

    Test.java

    package com.qb.spring.tx;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class Test {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
            GoodService goodService = (GoodService)applicationContext.getBean("goodService");
            goodService.buyGoods("aa", "1");
        }
    }
    application.xml
    <?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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
      <!-- 扫描注解-->
    <context:component-scan base-package="com.qb.spring.tx"></context:component-scan>    <!-- 加入配置文件db.properties -->
    <context:property-placeholder location="classpath:db.properties" />
        <!-- 配置数据源 -->
         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> </bean>

      <!-- 配置 Spring的NamedParamterJdbcTemplate 只能构造器注入dataSource -->
      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 配置事务管理器 -->
        <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 启用事务的注解 -->
            <tx:annotation-driven transaction-manager="transactionManager"/>
            
    </beans>

    db.propertice

    driverClass=com.mysql.jdbc.Driver//数据库驱动
    jdbcUrl=jdbc:mysql:///0912 //数据库路径
    user=root //数据库用户名
    password=123456 //数据库密码

    数据库代码:

    create table goods(
        id varchar(50) primary key,
        good_name varchar(100),
        price int
    );
    
    create table good_numbers(
        id varchar(50) primary key,
        number int,
        check(number > 0)
    );
    
    create table users(
        username varchar(50) primary key,
        balance int, 
        check(balance >0)
    );
    
    
    insert into goods(id,good_name,price) values('1','java',250);
    insert into goods(id,good_name,price) values('2','javaweb',125);
    
    insert into good_numbers(id,number) values('1',10);
    insert into good_numbers(id,number) values('2',10);
    
    insert into users(username,balance) values('aa',1000);
    insert into users(username,balance) values('bb',1000);

     
  • 相关阅读:
    AB测试原理及样本量计算的Python实现
    数据分析-A/B test
    数据分析-分类分析
    数据分析-漏斗模型(AARRR模型)
    置信区间的I型错误和II型错误
    tableau 计算字段
    tableau数据分层、数据组、数据集
    tableau 地图
    tableau 进阶
    tableau 基础
  • 原文地址:https://www.cnblogs.com/qiubin/p/7522535.html
Copyright © 2020-2023  润新知