• Spring学习笔记:声明式事务管理增删改查业务


    一、关于是事务

      以方法为单位,进行事务控制;抛出异常,事务回滚。

      最小的执行单位为方法。决定执行成败是通过是否抛出异常来判断的,抛出异常即执行失败

    二、声明式事务:

    声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一。
    Spring的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中声明。用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可;在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。
    Spring使用AOP来完成声明式的事务管理,因而声明式事务是以方法为单位,Spring的事务属性自然就在于描述事务应用至方法上的策略,在Spring中事务属性有以下四个参数:
    1.传播行为
    3.只读提示
    4.事务超时期间

    三、案例:编程实现购买股票的业务

      

      1.编写实体类

      2.编写dao层接口和实现

      3.编写service层接口和实现

    public class StockServiceImpl implements IStockService{
        private IStockDao stockDao;
        private IAccountDao accountDao;
    
        public void setStockDao(IStockDao stockDao) {
            this.stockDao = stockDao;
        }
    
        public void setAccountDao(IAccountDao accountDao) {
            this.accountDao = accountDao;
        }
    
        @Override
        public void buyStock(int sid, double scount, int aid, double abalance) {
            boolean isBuy = true;
            stockDao.updateStock(sid,scount,isBuy);
            accountDao.updateAccount(aid,abalance,isBuy);
        }
        @Override
        public void sellStock(int sid, double scount, int aid, double abalance) {
            boolean isBuy = false;
            stockDao.updateStock(sid,scount,isBuy);
            accountDao.updateAccount(aid,abalance,isBuy);
        }
    }

      4.编写applicationContext.xml引入架包

        (1)没有加入事务的xml文件

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="database.properties"/>
        </bean>
        <!--配置jdbc数据源-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="url" value="${jdbc.url}"></property>
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
        <!--注册jdbcTemplate-->
        <bean id="jbdcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--注册dao实现-->
        <bean id="accountDao" class="cn.bank.dao.impl.AccountDaoImpl">
            <property name="jdbcTemplate" ref="jbdcTemplate"/>
        </bean>
        <bean id="stockDao" class="cn.bank.dao.impl.StockDaoImpl">
            <property name="jdbcTemplate" ref="jbdcTemplate"/>
        </bean>
        <!--注册service实现-->
        <bean id="stockService" class="cn.bank.service.impl.StockServiceImpl">
            <property name="accountDao" ref="accountDao"/>
            <property name="stockDao" ref="stockDao"/>
        </bean>

        功能测试:

    @Test
        public void buyStock(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            IStockService stockService = (IStockService) context.getBean("stockService");
            stockService.buyStock(1001,1000,1204,10000);
        }

    (此处没有关联股票价格)

       (2)加入异常测试

    @Override
    public void buyStock(int sid, double scount, int aid, double abalance) {
    boolean isBuy = true;
    stockDao.updateStock(sid,scount,isBuy);
    if (1==1) {
    int i = 5 / 0;
    }
    accountDao.updateAccount(aid,abalance,isBuy);
    }

      报错:

      处理结果:

     

      在执行一次:

     

      现在我们可以看到,在增加股票和减少余额中间产生异常之后,股票增加而余额没有减少,这种现在肯定是错误的。

      (3)添加事务管理

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!--通过bean元素生命需要Spring创建的实例。该实例的类型通过class属性指定,
        并通过id属性为该实例制定一个名称,以便于访问-->
        <!--引入数据库配置文件-->
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="database.properties"/>
        </bean>
        <!--配置jdbc数据源-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="url" value="${jdbc.url}"></property>
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
        <!--注册jdbcTemplate-->
        <bean id="jbdcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--注册dao实现-->
        <bean id="accountDao" class="cn.bank.dao.impl.AccountDaoImpl">
            <property name="jdbcTemplate" ref="jbdcTemplate"/>
        </bean>
        <bean id="stockDao" class="cn.bank.dao.impl.StockDaoImpl">
            <property name="jdbcTemplate" ref="jbdcTemplate"/>
        </bean>
        <!--注册service实现-->
        <bean id="stockService" class="cn.bank.service.impl.StockServiceImpl">
            <property name="accountDao" ref="accountDao"/>
            <property name="stockDao" ref="stockDao"/>
        </bean>
        <!--引入事务平台管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--事务拦截处理:使用代理工厂-->
        <bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="target" ref="stockService"/>
            <property name="transactionManager" ref="transactionManager"/>
            <!--事务参数的设定-->
            <property name="transactionAttributes">
                <props>
                    <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
    </beans>

      测试(修改getBean()方法的参数):

    @Test
        public void buyStockTest(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            IStockService stockService = (IStockService) context.getBean("serviceProxy");
            stockService.buyStock(1001,1000,1204,10000);
        }

      异常发生,数据没有改变(是我们预期的结果,也是业务需要的):

        最后,去掉异常,保证事务管理下业务功能正常:

    四:业务实现正常

  • 相关阅读:
    SQL Server控制语句
    MATLAB中取整函数(fix, floor, ceil, round)的使用
    MATLAB程序设计
    Thinking In Java<<Java编程思想>>
    Boost::bimap
    MySQL学习随笔1
    Boost 1_42_0在windows下的编译及其设置
    MySQL执行mysql脚本及其脚本编写
    Pygame介绍
    Erlang
  • 原文地址:https://www.cnblogs.com/tengqiuyu/p/7698694.html
Copyright © 2020-2023  润新知