zoukankan      html  css  js  c++  java
  • SSM-Spring-21:Spring中事物的使用案例

     
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------

    股票买卖案例(我会用三种开启事物的方法 代理工厂bean版的,注解版的,aspectj xml版的)

      简单的介绍一下这个小例子,就是俩个表,一个就是你的账户表,一张就是你的股票的表

      一切从简,写的简单一点(你可以看成有很多不严谨的地方,只是一个Spring中的事务的简单使用,仅供理解事务,不用想太多)

      之前的那些jar包就不说了,从案例开始

    01.数据库准备:

      01.1账户表Account

        

      01.2股票表Stock

        

    02.IDEA中分层开发:

      02.1实体类(前面俩个实体类可以说在这个例子里没有用到,但是这是一种习惯)

        StockInfo表

    package cn.dawn.day22tx.entity;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class StockInfo {
        private Integer sid;
        private String sname;
        private Integer scount;
    
        public Integer getSid() {
            return sid;
        }
    
        public void setSid(Integer sid) {
            this.sid = sid;
        }
    
        public String getSname() {
            return sname;
        }
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        public Integer getScount() {
            return scount;
        }
    
        public void setScount(Integer scount) {
            this.scount = scount;
        }
    }

        AccountInfo表

    package cn.dawn.day22tx.entity;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class AccountInfo {
        private Integer aid;
        private String aname;
        private Integer ablance;
    
        public Integer getAid() {
            return aid;
        }
    
        public void setAid(Integer aid) {
            this.aid = aid;
        }
    
        public String getAname() {
            return aname;
        }
    
        public void setAname(String aname) {
            this.aname = aname;
        }
    
        public Integer getAblance() {
            return ablance;
        }
    
        public void setAblance(Integer ablance) {
            this.ablance = ablance;
        }
    }

        StockException类

    package cn.dawn.day22tx.entity;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class StockException extends ClassNotFoundException {
        public StockException() {
        }
    
        public StockException(String s) {
            super(s);
        }
    }

        这个类有点要说的,Spring的事务中执行一半遇到异常怎么操作?默认情况下是运行异常会回滚/受查异常会提交这执行过的代码,所以我做了个受查异常,一会可以测试一下

      02.2dao层,一个对股票表操作,一个对账户表操作

        IStockDAO股票接口

    package cn.dawn.day22tx.dao;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public interface IStockDAO {
        public boolean updateStock(int sid,int scount,boolean isBuy);
    }

        StockDAOImpl股票接口的实现类

    package cn.dawn.day22tx.dao;
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class StockDAOImpl extends JdbcDaoSupport implements IStockDAO {
        public boolean updateStock(int sid, int scount, boolean isBuy) {
            String sql="";
            boolean flag=false;
            if (isBuy){
                //买股票
                sql="update stock set scount=scount+? where sid=?";
            }else {
                sql="update stock set scount=scount-? where sid=?";
            }
            int result = this.getJdbcTemplate().update(sql,scount,sid);
            if (result>0) {
                flag = true;
            }
            return flag;
        }
    }

        这儿我将isBuy的布尔变量当等于true的时候,进行买股票操作,你的股票表上的股票股数增加

        IAccountDAO账户接口

    package cn.dawn.day22tx.dao;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public interface IAccountDAO {
        public boolean updateAccount(int aid,int ablance,boolean isBuy);
    }

        AccountDAOImpl账户的实现类

    package cn.dawn.day22tx.dao;
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class AccountDAOImpl extends JdbcDaoSupport implements IAccountDAO {
        public boolean updateAccount(int aid, int ablance, boolean isBuy) {
            String sql="";
            boolean flag=false;
            if(isBuy){
                //买股票
                sql="update account set ablance=ablance-? where aid=?";
            }else {
                sql="update account set ablance=ablance+? where aid=?";
            }
            int count = this.getJdbcTemplate().update(sql, ablance, aid);
            if(count>0){
                flag=true;
            }
            return flag;
        }
    }

      02.3service层

        股票的交易接口IStockPayService

    package cn.dawn.day22tx.service;
    
    import cn.dawn.day22tx.entity.StockException;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public interface IStockPayService {
        public boolean buyStock(int aid,int ablance,int sid,int scount) throws StockException;
    }

        股票交易的实现类StockPayServiceImpl

    package cn.dawn.day22tx.service;
    
    import cn.dawn.day22tx.dao.IAccountDAO;
    import cn.dawn.day22tx.dao.IStockDAO;
    import cn.dawn.day22tx.entity.StockException;
    import org.springframework.transaction.annotation.Transactional;
    
    /**
     * Created by Dawn on 2018/3/15.
     */
    public class StockPayServiceImpl implements IStockPayService {
        IStockDAO iStockDAO;
        IAccountDAO iAccountDAO;
        //@Transactional(rollbackFor = StockException.class)
        public boolean buyStock(int aid, int ablance, int sid, int scount) throws StockException {
            boolean isBuy=true;
            boolean sflag = iStockDAO.updateStock(sid, scount, isBuy);
    
            if(true){
                throw new StockException("网络被挂掉异常");
            }
    
            boolean aflag = iAccountDAO.updateAccount(aid, ablance, isBuy);
    
            if(sflag&&aflag)
                return true;
            else
                return false;
        }
    
        public IStockDAO getiStockDAO() {
            return iStockDAO;
        }
    
        public void setiStockDAO(IStockDAO iStockDAO) {
            this.iStockDAO = iStockDAO;
        }
    
        public IAccountDAO getiAccountDAO() {
            return iAccountDAO;
        }
    
        public void setiAccountDAO(IAccountDAO iAccountDAO) {
            this.iAccountDAO = iAccountDAO;
        }
    }

        看到那个方法上面注释掉的那个注解了吗?那是第二种方式要用到,只有在第二种方式注解版的时候才用到,其他俩种方式就注释掉它,免得有干扰,切记,用的时候把注释消掉,不用就注释它

        @Transactional里面我只写了遇到什么异常会回滚,它的传播行为和隔离级别有默认值,我就省略了

    03.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:p="http://www.springframework.org/schema/p"
           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/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">
    
        <!--配置jdbc。properties-->
        <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    
    
        <!--阿里的Druid-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
        
    
        <!--dao层-->
        <bean id="stockDAO" class="cn.dawn.day22tx.dao.StockDAOImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <bean id="accountDAO" class="cn.dawn.day22tx.dao.AccountDAOImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!--service-->
        <bean id="stockpPayService" class="cn.dawn.day22tx.service.StockPayServiceImpl">
            <property name="iAccountDAO" ref="accountDAO"></property>
            <property name="iStockDAO" ref="stockDAO"></property>
        </bean>
        
        <!--事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--第三种方式 aspectj xml版-->
        <tx:advice id="txadvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
            </tx:attributes>
        </tx:advice>
        <aop:config>
            <aop:pointcut id="mypointccut" expression="execution(* *..day22tx.service.*.*(..))"></aop:pointcut>
            <aop:advisor advice-ref="txadvice" pointcut-ref="mypointccut"></aop:advisor>
        </aop:config>
    
        <!--第二种事务开启方式,注解版-->
        <!--<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>-->
    
        <!--第一种事务开启方式代理工厂-->
        <!--<bean id="txService"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager" ref="transactionManager"></property>
            <property name="target" ref="stockpPayService"></property>
            <property name="transactionAttributes">
                <props>
                    <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop>
                </props>
            </property>
        </bean>-->
    </beans>

      没什么需要说的,这儿像什么命名空间等需要注意一点,其他的就是照猫画虎

      有什么不清楚的评论留言,我会帮忙解决

    04.单测方法:

    package cn.dawn.day22tx;
    
    
    import cn.dawn.day22tx.entity.StockException;
    import cn.dawn.day22tx.service.IStockPayService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    /**
     * Created by Dawn on 2018/3/3.
     */
    public class test20180315 {
        @Test
        /*aspectj xml方式*/
        public void t03() {
            ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
            IStockPayService service = (IStockPayService) context.getBean("stockpPayService");
            boolean flag = false;
            try {
                flag = service.buyStock(1, 100, 1, 20);
            } catch (StockException e) {
                e.printStackTrace();
            }
            if(flag){
                System.out.println("购买成功");
            }
    
        }
    
    
        @Test
        /*注解方式*/
        public void t02() {
            ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
            IStockPayService service = (IStockPayService) context.getBean("stockpPayService");
            boolean flag = false;
            try {
                flag = service.buyStock(1, 100, 1, 20);
            } catch (StockException e) {
                e.printStackTrace();
            }
            if(flag){
                System.out.println("购买成功");
            }
    
        }
    
        @Test
        /*代理工厂bean的方式*/
        public void t01() {
            ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext-day22tx.xml");
            IStockPayService service = (IStockPayService) context.getBean("txService");
            boolean flag = false;
            try {
                flag = service.buyStock(1, 100, 1, 20);
            } catch (StockException e) {
                e.printStackTrace();
            }
            if(flag){
                System.out.println("购买成功");
            }
    
        }
    }

      简述一下运行结果,单测成功,中途会打印异常信息,由于开启了事务,同生共死,俩张表在数据库都没有改变值,事务的出口被回滚了

  • 相关阅读:
    Windows Mobile 开发资源 [转]
    CIO与CTO的区别
    [转]快速产品开发的12项指南
    VS Template Parameters
    MSDN Webcast 使用Windows Mobile Test Framework进行自动化测试(Level 300)
    10年内两类必被淘汰的企业软件开发公司(转载)
    小学期第二周收获
    对于学长创作的软件 TD信息通(无课表)的使用体验以及改进内容
    小学期第一周收获
    Delphi中建议使用的语句
  • 原文地址:https://www.cnblogs.com/DawnCHENXI/p/8575562.html
Copyright © 2011-2022 走看看