zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    20165312 我期望的师生关系
    zookeeper04---ZAB协议
    zookeeper03-集群搭建
    zookeeper02
    Zookeeper01
    防止重复提交
    手动抛出异常事务回滚问题
    redis-07主从复制
    redis06-事务
    Redis-05持久化
  • 原文地址:https://www.cnblogs.com/my-123/p/8584278.html
Copyright © 2011-2022 走看看