• Spring声明式事务


    假设一个人去4s店买车,需要修改数据库中车辆库存和user的余额,选好车后发现没钱肯定不能提车即事务(如果有可以买车不付钱的地方请带上我)

    xml文件配置

    资源文件

    user=root
    password=****
    driverClass=com.mysql.jdbc.Driver
    jdbcUrl=jdbc:mysql://127.0.0.1:3306/test
    
    initPoolSize=5
    maxPoolSize=10
    <?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:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
         <!-- 配置自动扫描的包 -->
        <context:component-scan base-package="com.spring.tx"></context:component-scan>
    
        <!-- 配置自动为匹配 aspectJ 注解的 Java 类生成代理对象 -->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        
        
        <!-- 导入资源文件 src目录下的db.propertier文件 -->
        <context:property-placeholder location="classpath:db.properties"/>
        
        <!-- 配置 C3P0 数据源 -->
         <bean id="dataSource"
            class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="user" value="${user}"></property>
            <property name="password" value="${password}"></property>
            <property name="jdbcUrl" value="${jdbcUrl}"></property>
            <property name="driverClass" value="${driverClass}"></property>
    
            <property name="initialPoolSize" value="${initPoolSize}"></property>
            <property name="maxPoolSize" value="${maxPoolSize}"></property>
        </bean>
        
        
        <!-- 配置 Spirng 的 JdbcTemplate -->
        <bean id="jdbcTemplate" 
            class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!--  配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 启用事务注解 -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
        
    
    </beans>

    Dao类

    package com.spring.tx;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Repository;
    
    /**
    * 
    * @version 创建时间:2017年8月15日 上午6:26:18
    * 类说明
    */
    @Repository("carDao")
    public class CarDao {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
        
        public int findCarPriceByName(String name) {
            String sql = "select price from car where name = ?";
            return jdbcTemplate.queryForObject(sql, Integer.class, name);
        }
        
        public void updataCarStock(String name) {
            String sql = "select stock from car where name = ?";
            int stock = jdbcTemplate.queryForObject(sql,Integer.class, name);
            if(stock<=0) {
                throw new StockException("库存不足");
            }        
            
            sql = "update car set stock = stock-1 where name = ?";
            jdbcTemplate.update(sql, name);
        }
        
        public void updataUserMoney(String name,int price) {
            String sql = "select money from user where name = ?";
            int money = jdbcTemplate.queryForObject(sql,Integer.class,name);
            if(money<price) {
                throw new MoneyException("穷------");  //QAQ
            }
            sql = "update user set money = ? where name = ?";
            money = money - price;
            jdbcTemplate.update(sql, money,name);
        }
        
    }

    需要抛出的异常类

    package com.spring.tx;
    /**
    * 
    * @version 创建时间:2017年8月15日 上午6:44:14
    * 类说明
    */
    public class StockException extends RuntimeException {
           //缺少库存
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        public StockException() {
            super();
        }
        public StockException(String massage) {
            // TODO Auto-generated constructor stub
            super(massage);
        }
    }
    
    
    package com.spring.tx;
    /**
    * 
    * @version 创建时间:2017年8月15日 上午6:46:56
    * 类说明
    */
    public class MoneyException extends RuntimeException{
    
         /**
         * 
         */
    //缺钱
        private static final long serialVersionUID = 1L;
    
        public MoneyException() {
            // TODO Auto-generated constructor stub
             super();
        }
        public MoneyException(String massage) {
            // TODO Auto-generated constructor stub
             super(massage);
        }
    }

    Service

    package com.spring.tx;
    /**
    * 
    * @version 创建时间:2017年8月15日 上午9:35:45
    * 类说明
    */
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service("carShopServlet")
    public class CarShopServlet {
        
        @Autowired
        private CarDao carDao;
        
        
        //添加事务注解
        @Transactional
        public void purchase(String username, String carname) {
            
            int price = carDao.findCarPriceByName(carname);
            
            carDao.updataCarStock(carname);
            
            carDao.updataUserMoney(username, price);
            
            //要是没事务就可以买车不付钱了
        }
    
    }

    Test

    package com.spring.tx;
    
    import static org.hamcrest.CoreMatchers.nullValue;
    import static org.junit.Assert.*;
    
    import java.sql.SQLException;
    
    import javax.sql.DataSource;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    /**
    * 
    * @version 创建时间:2017年8月15日 上午7:00:01
    * 类说明
    */
    public class Test {
    
        private ApplicationContext ctx = null;
        private CarShopServlet carShopServlet =null;
        
        
        
        {
            ctx = new ClassPathXmlApplicationContext("beans-tx.xml");
            carShopServlet = (CarShopServlet) ctx.getBean("carShopServlet");
        
        }
        @org.junit.Test
        public void testtx() {
            
            
            carShopServlet.purchase("关羽", "福特");
            
            carShopServlet.purchase("关羽", "兰博基尼");
        }
        
        
        
        
        @org.junit.Test
        public void testcon() throws SQLException {//测试是否连上数据库
            // TODO Auto-generated constructor stub
            
            DataSource dataSource = (DataSource) ctx.getBean("dataSource");
            System.out.println(dataSource.getConnection());
            /*JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
            System.out.println(jdbcTemplate);*/
        }
        
    
        
    
    }

    运行前数据

     运行后

    买了福特 但是买不起兰博基尼

    基于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:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    
        <!-- 配置自动扫描的包 -->
        <context:component-scan base-package="com.spring.tx.xml"></context:component-scan>
    
        <!-- 配置自动为匹配 aspectJ 注解的 Java 类生成代理对象 -->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        
        
        <!-- 导入资源文件 -->
        <context:property-placeholder location="classpath:db.properties"/>
        
        <!-- 配置 C3P0 数据源 -->
         <bean id="dataSource"
            class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="user" value="${user}"></property>
            <property name="password" value="${password}"></property>
            <property name="jdbcUrl" value="${jdbcUrl}"></property>
            <property name="driverClass" value="${driverClass}"></property>
    
            <property name="initialPoolSize" value="${initPoolSize}"></property>
            <property name="maxPoolSize" value="${maxPoolSize}"></property>
        </bean>
        
        
        <!-- 配置 Spirng 的 JdbcTemplate -->
        <bean id="jdbcTemplate" 
            class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!--  配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!-- 启用事务注解 -->
        <!--  <tx:annotation-driven transaction-manager="transactionManager"/>-->
        
        <!--  配置事务属性 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 根据方法名指定事务的属性 -->
                <!-- 事务传播属性 默认为REQUIRES -->
                <tx:method name="purchase" propagation="REQUIRES_NEW"/>
                <tx:method name="get*" read-only="true"/>
                <tx:method name="find*" read-only="true"/>
            </tx:attributes>
        </tx:advice>
        
        <!--  配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
        <aop:config>
             <!-- 此包下的所有类的所有方法其实只有purchase一个方法 -->
            <aop:pointcut expression="execution(* com.spring.tx.xml.service.*.*(..))" 
                id="txPointCut"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>    
        </aop:config>
    
    </beans>
  • 相关阅读:
    Error:dojo.data.ItemFileWriteStore:Invalid item argument
    TypeError:_12.store.query is not a function
    Error:dijit.tree.TreeStoreModel:root query returned 0 items
    dijit.byId("grid") is undefined
    ORA-00600:internal error code,arguments:[keltnfy-idmlnit],[46],[1],[],[],[],[],[]
    gc cr block busy
    gc buffer busy acquire
    gc cr request
    LVS+Keepalived实现高可用集群
    关于函数授权问题
  • 原文地址:https://www.cnblogs.com/lusufei/p/7363745.html
Copyright © 2020-2023  润新知