Spring(十二)Spring之事务

java中事务是什么?

事务是访问数据库的一个操作序列,DB应用系统通过事务集来完成对数据的存取。

 

事务必须遵循4个原则,即常说的 ACID

 

A,Automicity,原子性,即事务要么被全部执行,要么被全部不执行。如果事务下的子事务全部提交成功,则所有数据库操作被提交,否则,应进行事务回滚。

 

C,Consistency,一致性,即状态转换必须是由一种正确的状态转换到另外一种正确的状态。

 

I,Isolation,隔离性,即相互间必须不能被影响。

 

D,Durabillity,持久性,即事务提交后将被永久保存,即便出现其他故障,事务处理结果也应得到保存。

 

事务的隔离级别

串行化,Serializable,一个事务在执行过程中完全看不到其他事务对数据库所做的更新。

可重复读,Repeatable Read,一个事务在执行过程中可以看到其他事务已经提交的记录,但是不能看到其他事务对已有记录的更新。

读已提交数据,Read Commited,一个事务在执行过程中可以看到其他事务已经提交的记录,而且能看到其他事务对已有记录的更新。

读未提交数据,Read UnCommited,一个事务在执行过程中可以看到其他事务没有提交的记录,而且能看到其他事务没有提交的记录的更新

 

简单介绍完事务之后,我们用一个例子来具体使用一下事务:购买股票的案例

第一步:准备工作

1)数据表

股票表:stock

账户余额表:account

2)实体类

Account类

package demo22tx.entity;

/**
 * Created by mycom on 2018/3/15.
 */
public class Account {
    private Integer aid;
    private String aname;

    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;
    }

    private Integer ablance;
}

Stock类

package demo22tx.entity;

import javax.jnlp.IntegrationService;

/**
 * Created by mycom on 2018/3/15.
 */
public class Stock {
    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;
    }
}

3)dao层

AccountDao接口

package demo22tx.dao;

/**
 * Created by mycom on 2018/3/15.
 */
public interface IAccountDao {
    public boolean updateAccount(int aid,int ablance,boolean isbuy);
}

AccountDaoImpl实现类

package demo22tx.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by mycom 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 balance=balance-? where aid=?";
        }else{
            sql="update account set balance=balance+? where aid=?";
        }
        int update = this.getJdbcTemplate().update(sql, ablance, aid);
        if(update>0){
            flag=true;
        }
        return flag;
    }
}

StockDao接口

package demo22tx.dao;

/**
 * Created by mycom on 2018/3/15.
 */
public interface IStockDao {
    public boolean updateStock(int sid,int count,boolean isbuy);
}

StockDaoImpl实现类

package demo22tx.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * Created by mycom on 2018/3/15.
 */
public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {
    public boolean updateStock(int sid, int count, boolean isbuy) {
        String sql="";
        boolean flag=false;
        if(isbuy){
            //买入购票
            sql="update stock set count=count+? where sid=?";
        }else{
            sql="update stock set count=count+? where sid=?";
        }
        int update = this.getJdbcTemplate().update(sql, count, sid);
        if(update>0){
            flag=true;
        }
        return flag;
    }
}

4)service层

IStockService接口

package demo22tx.service;

import demo22tx.entity.StockException;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by mycom on 2018/3/15.
 */
public interface IStockService {
    public boolean buyStock(int aid,int abalance,int sid,int count) throws StockException;
}

StockServiceImpl实现类

package demo22tx.service;

import demo22tx.dao.IAccountDao;
import demo22tx.dao.IStockDao;
import demo22tx.entity.StockException;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by mycom on 2018/3/15.
 */
public class StockServiceImpl implements IStockService{
    private IAccountDao accountDao;
    private IStockDao stockDao;
    @Transactional
    public boolean buyStock(int aid, int abalance, int sid, int count) throws StockException {
        boolean isbuy=true;
        //异常
        if(1==1){
            throw new StockException("出错了");
        }
        boolean account = accountDao.updateAccount(aid, abalance, isbuy);
        boolean stock = stockDao.updateStock(sid, count, isbuy);
        if(account&&stock){
            return true;
        }else{
            return false;
        }
    }

    public IAccountDao getAccountDao() {
        return accountDao;
    }

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public IStockDao getStockDao() {
        return stockDao;
    }

    public void setStockDao(IStockDao stockDao) {
        this.stockDao = stockDao;
    }
}

第二步:配置文件

JDBC.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///s2228
jdbc.username=root
jdbc.password=
applicationContextdemo22tx.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: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">

    <!--配置数据源-->
    <bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <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>

    <!--识别到jdbc.properties-->
    <!--配置1-->
    <!--<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>-->
    <!--配置2-->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties"></property>
    </bean>
    <!--配置Dao-->
    <bean id="accountDao" class="demo22tx.dao.AccountDaoImpl">
        <property name="dataSource" ref="dateSource"></property>
    </bean>
    <bean id="stockDao" class="demo22tx.dao.StockDaoImpl">
        <property name="dataSource" ref="dateSource"></property>
    </bean>
    <!--service id-->
    <bean id="stockService" class="demo22tx.service.StockServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <property name="stockDao" ref="stockDao"></property>
    </bean>
    <!--事务-->
    <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dateSource"></property>
    </bean>
    <!--事务代理工厂bean  方式一-->
    <!--<bean id="stockServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">-->
    <!--<property name="transactionManager" ref="transactionManager"></property>-->
    <!--<property name="target" ref="stockService"></property>-->
    <!--<property name="transactionAttributes">-->
        <!--<props>-->
            <!--<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>-->
        <!--</props>-->
        <!--</property>-->
    <!--</bean>-->
    <!--事务代理工厂bean  方式二-->
    <!--<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>-->
    <!--事务代理工厂bean  方式三-->
    <tx:advice id="stockAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="mypointcut" expression="execution(* demo22tx.service.*.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="stockAdvice" pointcut-ref="mypointcut"></aop:advisor>
    </aop:config>
</beans>

第三步:测试类

import demo21.entity.Book;
import demo21.service.IBookservice;
import demo22tx.entity.StockException;
import demo22tx.service.IStockService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * Created by mycom on 2018/3/3.
 */
public class TestTrasaction20180315 {
    //JDBCtemplate测试类
    @Test
    public void t1() throws StockException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextdemo22tx.xml");
        IStockService stockService =(IStockService) context.getBean("stockService");
        stockService.buyStock(1,100,1,10);
    }
}

 

posted @ 2018-03-16 19:19  明渃筱曦  阅读(167)  评论(0编辑  收藏  举报