Spring事物管理(二)

Spring事物处理规则:

运行时异常,默认回滚。

编译异常,默认提交。

 

事物案例:购买股票

数据库脚本

/*
SQLyog v10.2 
MySQL - 5.6.24 : Database - y2167
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`y2167` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `y2167`;

/*Table structure for table `account` */

DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (
  `aid` INT(11) NOT NULL AUTO_INCREMENT,
  `aname` VARCHAR(20) DEFAULT NULL,
  `balance` INT(11) DEFAULT NULL,
  PRIMARY KEY (`aid`)
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/*Data for the table `account` */

insert  into `account`(`aid`,`aname`,`balance`) values (1,'xcq',60000);

/*Table structure for table `stock` */

DROP TABLE IF EXISTS `stock`;

CREATE TABLE `stock` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(30) DEFAULT NULL,
  `count` int(11) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `stock` */

insert  into `stock`(`sid`,`sname`,`count`) values (1,'股票A',5),(2,'股票B',20),(3,'股票C',30);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

创建DAO和Service层

//DAO层

package cn.happy.day15tx.dao;

/**
 * Created by Administrator on 2018/3/14.
 */
//账户
public interface IAccountDAO {
    public void updateAccount(int aid,int balance,boolean isBuy);
}


-------------------------------------------------------------------------

public interface IStockDAO {
    //改变股票数量
    public void updateIStock(int sid,int count,boolean isBuy);
}


-------------------------------------------------------------------------

//DAOImpl

package cn.happy.day15tx.dao.impl;

import cn.happy.day15tx.dao.IStockDAO;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by Administrator on 2018/3/14.
 */

//卖出
public class StockDaoImpl extends JdbcDaoSupport implements IStockDAO {
    public void updateIStock(int sid, int count, boolean isBuy) {
        String sql=null;
        if(isBuy){
            //增加股票
            sql="update Stock set count=count+? where sid=?";
        }else{
            //卖出股票
            sql="update Stock set count=count-? where sid=?";
        }

        this.getJdbcTemplate().update(sql,count,sid);
    }
}



-------------------------------------------------------------------------

package cn.happy.day15tx.dao.impl;

import cn.happy.day15tx.dao.IAccountDAO;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by Administrator on 2018/3/14.
 */

//买入
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDAO {

    public void updateAccount(int aid, int balance, boolean isBuy) {
        String sql=null;
        if(isBuy){
            //购买
            sql="update Account set balance=balance-? where aid=?";
        }else{
            //卖出
            sql="update Account set balance=balance+? where aid=?";
        }

        this.getJdbcTemplate().update(sql,balance,aid);
    }
}


------------------------------------------------------------------------
Service

package cn.happy.day15tx.service;


/**
 * Created by Administrator on 2018/3/14.
 */
public interface IStockService {
    //购买股票
    public void updateStock(int aid,int balance,int sid,int count) throws Exception, Exception;
}


------------------------------------------------------------------------
ServiceImpl

package cn.happy.day15tx.service.impl;

import cn.happy.day15tx.dao.IAccountDAO;
import cn.happy.day15tx.dao.IStockDAO;
import cn.happy.day15tx.service.IStockService;
import com.sun.javafx.beans.annotations.Default;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by Administrator on 2018/3/14.
 */

public class StockServiceImpl implements IStockService {
    //植入DAO层对象
    private IAccountDAO accountDAO;
    private IStockDAO iStockDAO;

    //使用注解
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateStock(int aid, int balance, int sid, int count) throws Exception {

        //创建boolean对象判断是买入true还是卖出false
        boolean isBuy=true;
        accountDAO.updateAccount(aid,balance,isBuy);
    //定义一个异常
        if(true)
        throw new Exception("出错了");

        iStockDAO.updateIStock(sid,count,isBuy);

    }

    public IAccountDAO getAccountDAO() {
        return accountDAO;
    }

    public void setAccountDAO(IAccountDAO accountDAO) {
        this.accountDAO = accountDAO;
    }

    public IStockDAO getiStockDAO() {
        return iStockDAO;
    }

    public void setiStockDAO(IStockDAO iStockDAO) {
        this.iStockDAO = iStockDAO;
    }
}



-------------------------------------------------------------
entity


package cn.happy.day15tx.entity;

/**
* Created by Administrator on 2018/3/14.
*/
//购票类
public class Account {
private Integer aid;
private String aname;
private Integer balance;

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 getBalance() {
return balance;
}

public void setBalance(Integer balance) {
this.balance = balance;
}
}



-------------------------------------------------------

package cn.happy.day15tx.entity;

/**
* Created by Administrator on 2018/3/14.
*/
//股票类
public class Stock {
private Integer sid;
private String sname;
private Integer count;

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 getCount() {
return count;
}

public void setCount(Integer count) {
this.count = count;
}
}


一、配置xml文件

<!--数据源-->
   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
   </bean>


    <!--识别jdbc.properties文件-->
   <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--DAO-->
    <bean id="StockDAO" class="cn.happy.day15tx.dao.impl.StockDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="AccountDAO" class="cn.happy.day15tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--service-->
    <bean id="StockService" class="cn.happy.day15tx.service.impl.StockServiceImpl">
        <property name="accountDAO" ref="AccountDAO"/>
        <property name="iStockDAO" ref="StockDAO"/>
    </bean>

    <!--事物管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--事物控制-->
   <!--方案一-->
    <bean id="stockServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <!--需要控制的类-->
        <property name="target" ref="StockService"/>
        <property name="transactionAttributes">
            <props>
                <!--控制的方法-->
                <prop key="updateStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-Exception</prop>
          <!--
            ISOLATION_DEFAULT 底层数据库默认隔离级别
            PROPAGATION_REQUIRED 如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务
            -Exception,设置回滚(设置异常,只要出现运行时异常就会回滚)
          -->
       </props>
     </property>
  </bean>

  

测试方法

package day15tx;

import cn.happy.JDBCTemplate.service.BookService;
import cn.happy.day15tx.service.IStockService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * Created by Administrator on 2018/3/3.
 */
public class Test20180314 {

    //事物
    @Test
    public void Spring(){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("day15tx.xml");
        IStockService service=(IStockService)ctx.getBean("stockServiceProxy");
        try{
            service.updateStock(1,2000,1,5);
        }catch (Exception e){
            e.printStackTrace();
        }

    }


}

  

二、使用注解管理事物

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       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.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--数据源-->
   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
   </bean>


    <!--识别jdbc.properties文件-->
   <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--DAO-->
    <bean id="StockDAO" class="cn.happy.day15tx.dao.impl.StockDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="AccountDAO" class="cn.happy.day15tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--service-->
    <bean id="StockService" class="cn.happy.day15tx.service.impl.StockServiceImpl">
        <property name="accountDAO" ref="AccountDAO"/>
        <property name="iStockDAO" ref="StockDAO"/>
    </bean>

    <!--事物管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--方案二:使用注解管理事物-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>

  

在需要管理的方法上添加注解

 @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,rollbackFor = Exception.class)

  

三、使用AspectJ实现事物管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       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.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--数据源-->
   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="${jdbc.driver}"/>
       <property name="url" value="${jdbc.url}"/>
       <property name="username" value="${jdbc.username}"/>
       <property name="password" value="${jdbc.password}"/>
   </bean>


    <!--识别jdbc.properties文件-->
   <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--DAO-->
    <bean id="StockDAO" class="cn.happy.day15tx.dao.impl.StockDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="AccountDAO" class="cn.happy.day15tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--service-->
    <bean id="StockService" class="cn.happy.day15tx.service.impl.StockServiceImpl">
        <property name="accountDAO" ref="AccountDAO"/>
        <property name="iStockDAO" ref="StockDAO"/>
    </bean>

    <!--事物管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--方案三:使用aspectJ AOP实现事物管理-->
   <!-- <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="updateStock" isolation="DEFAULT" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!–切点–>
        <aop:pointcut id="mypoint" expression="execution(* *..day15tx.service.*.*(..))"></aop:pointcut>
        <!–顾问–>
        <aop:advisor advice-ref="advice" pointcut-ref="mypoint"></aop:advisor>
    </aop:config>-->

</beans>

  

原文地址:https://www.cnblogs.com/xuchangqi1/p/8581634.html