Spring 实现事务的三种方式

事务:保证数据的运行不会说A给B钱,A钱给了B却没收到。

实现事务的三种方式(重要代码):

1.aspectJ AOP实现事务:

<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dateSource"></property>
</bean>
<tx:advice id="stockAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="by*" isolation="DEFAULT" propagation="REQUIRED" rollback-for="MyExepction"/>
<tx:method name="select*" isolation="DEFAULT" propagation="REQUIRED" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="exAdvice" expression="execution(* *..service.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="stockAdvice" pointcut-ref="exAdvice"></aop:advisor>
</aop:config>

2.事务代理工厂Bean实现事务:

<bean id="tproxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="dataSourceTransactionManager"></property>&lt;!&ndash;写的是事务&ndash;&gt;
<property name="target" ref="byStockService"></property>&lt;!&ndash;要进行事务的类&ndash;&gt;
<property name="transactionAttributes">
<props>&lt;!&ndash;key写的是service层要增强的方法&ndash;&gt;
&lt;!&ndash; 事务的隔离级别,后面逗号后面是异常类,用于回滚数据&ndash;&gt;
<prop key="ByStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-MyExepction</prop>
</props>
</property>
</bean>

3.注解方式实现事务:

<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
在需要进行事务的方法上增加一个注解“
@Transactional(rollbackFor = MyExepction.class )

做一个买股票的小例子来看一下事务:

1.使用事务工厂Bean

xml:

这个异常刚好卡在支付金额,和股票增加直接,

 RuntimeException是运行时异常
Exception是检查异常
两者的区别:
运行时异常是默认回滚,
检查异常是默认提交的。

 数据表:

 结果异常出现后,数据进行了回滚,A表中并没有少余额,B表中也没有多股票。

基本的架构:

  dao:                                                                           

IStockDao:
package cn.Spring.Day20xy.dao;

public interface IStockDao {
    public int updateStock(int sid,int soucnt,boolean isbuay)throws Exception;
}
IAccountDao:
package cn.Spring.Day20xy.dao;

public interface IAccountDao {
    public int updateAccount(int aid,Double amoeny,boolean isbay) throws Exception;
}
StockDaoImpl:
package cn.Spring.Day20xy.dao;

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

public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {

    @Override
    public int updateStock(int sid, int soucnt, boolean isbuay) throws Exception {
        String sql="";
        if (isbuay){
            sql="update stock set scount=scount+? where sid=?";
        }else {
            sql="update stock set scount=scount-? where sid=?";
        }
        return this.getJdbcTemplate().update(sql,soucnt,sid);
    }
}
AccountDaoImpl:
package cn.Spring.Day20xy.dao;

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

public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao{
    @Override
    public int updateAccount(int aid,Double amoeny,boolean isbay) throws Exception {
        String sql="";
        if (isbay){
            sql="update account set abalance=abalance-? where aid=?";
        }else {
            sql="update account set abalance=abalance+? where aid=?";
        }
        return this.getJdbcTemplate().update(sql,amoeny,aid);
    }
}

  entity:                                                                           

Account:
package cn.Spring.Day20xy.entity;

public class Account {
    private Integer aid;
    private String aname;
    private double abalance;

    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 double getAbalance() {
        return abalance;
    }

    public void setAbalance(double abalance) {
        this.abalance = abalance;
    }
}

  

Stock:
package cn.Spring.Day20xy.entity;

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;
    }
}
MyExepction:
package cn.Spring.Day20xy.entity;

public class MyExepction extends RuntimeException {
    public MyExepction() {
    }

    public MyExepction(String message) {
        super(message);
    }


}

  service:                                                                           

IByStockService :

package cn.Spring.Day20xy.service;

public interface IByStockService {
    public int ByStock(int aid,double moeny,int sid ,int count)throws Exception;
}
ByStockServiceImpl:
package cn.Spring.Day20xy.service;

import cn.Spring.Day20xy.dao.IAccountDao;
import cn.Spring.Day20xy.dao.IStockDao;
import cn.Spring.Day20xy.entity.MyExepction;
import org.springframework.transaction.annotation.Transactional;

public class ByStockServiceImpl implements IByStockService{
    //植入Dao
    private IAccountDao accountDao;
    private IStockDao stockDao;

    @Override
    @Transactional(rollbackFor = MyExepction.class )
    public int ByStock(int aid,double moeny,int sid ,int count) throws Exception {
        boolean isbay=true;
        int i = accountDao.updateAccount(aid, moeny, isbay);
       if (1==1) {
           throw new MyExepction("出异常了");
       }
        int i1 = stockDao.updateStock(sid, count, isbay);
        return i+i1;
    }

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

  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: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/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">
    <!--1.配置数据源-->
    <bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///newss2230"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123"></property>
    </bean>
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--2.JDBCTampLate-->
    <bean id="jdbcTempLate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dateSource"></property>
    </bean>
    <!--3.Dao-->
    <bean id="accountDao" class="cn.Spring.Day20xy.dao.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTempLate"></property>
    </bean>
    <!--3.Dao-->
    <bean id="stockDao" class="cn.Spring.Day20xy.dao.StockDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTempLate"></property>
    </bean>
    <!--4.Service-->
    <bean id="byStockService" class="cn.Spring.Day20xy.service.ByStockServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <property name="stockDao" ref="stockDao"></property>

        <!--事务-->
    </bean>
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dateSource"></property>
    </bean>

    <!--事务注解驱动-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
    <!--事务代理工厂bean-->
    <!--<bean id="tproxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
        <property name="target" ref="byStockService"></property>
      <property name="transactionAttributes">
          <props>&lt;!&ndash;key写的是service层的方法&ndash;&gt;
              <prop key="ByStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-MyExepction</prop>
          </props>
      </property>
    </bean>-->
</beans>
原文地址:https://www.cnblogs.com/java-263/p/10079806.html