人工管理 con.beginTransaction
事务声明式
编程式事务 :手动提交事务,开始事务
spring事务的抽象
1 平台事务管理器
Platform transaction manager 接口
作用 : 为各个框架进行事务管理
TransactionDetinition 事务定义 接口
TransctionStatus 事物状态 接口
现在开始 进行 案例 进行事务练习
数据库
这是进行案例的数据库 一 一个用户 二 股票
现在开始代码的书写
一 实体类
public class Account { private Integer aid; private String aname; private Integer 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 Integer getAbalance() { return abalance; } public void setAbalance(Integer abalance) { this.abalance = abalance; } }
public class Stock { private Integer sid; private String name; private Integer Scount; public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getScount() { return Scount; } public void setScount(Integer scount) { Scount = scount; } }
现在开始接口的书写
public interface Buy { public boolean abuy(int aid,int abalance,boolean isBuy); }
public interface ABuy { public boolean Buystock(int sid,int scount,boolean isBuy); }
一个为用户的 一个为股票的
实现类
package JIHE.DAO.impl; import JIHE.DAO.Buy; import org.springframework.jdbc.core.support.JdbcDaoSupport; /** * Created by 维吉的笔记本 on 2018/3/15. */ public class Buyimpl extends JdbcDaoSupport implements Buy { public boolean abuy(int aid, int abalance, boolean isBuy) { String sql; if(isBuy){ sql="update auser set amoney=amoney-? where aid=?"; }else{ sql="update auser set amoney=amoney+? where aid=?"; } int update = this.getJdbcTemplate().update(sql, abalance, aid); boolean flag=false; if(update>0){ flag=true; }else{ flag=false; } return flag; } }
package JIHE.DAO.impl; import JIHE.DAO.ABuy; import org.springframework.jdbc.core.support.JdbcDaoSupport; /** * Created by 维吉的笔记本 on 2018/3/15. */ public class ABuyimpl extends JdbcDaoSupport implements ABuy { public boolean Buystock(int sid,int scount,boolean isBuy) { String sql; if(isBuy){ sql="update stoke set smoney=smoney+? where sid=?"; }else{ sql="update stoke set smoney=smoney-? where sid=?"; } int update = this.getJdbcTemplate().update(sql,scount, sid); boolean flag=false; if(update>0){ flag=true; }else{ flag=false; } return flag; } }
现在 看书写方法 继承 JdbcDaoSupport 实现 接口方法 编写sql语句 ,通过 boolean来判断是否买入卖出,
this.getJdbcTemplate().update的方法来使用sql
现在开始写service层
先写接口
public interface Bu { public boolean bu(int aid,int acount,int sid,int scount) throws Spt; }
为上面两个方法准备使用的参数 ,因为购买时需要同时进行 用户和股票的改动
现在开始 实现类
package JIHE.service.impl; import JIHE.DAO.ABuy; import JIHE.DAO.Buy; import JIHE.Except.Spt; import JIHE.service.Bu; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** * Created by 维吉的笔记本 on 2018/3/15. */ public class Buimpl implements Bu { private Buy a; private ABuy b; public Buy getA() { return a; } public void setA(Buy a) { this.a = a; } public ABuy getB() { return b; } public void setB(ABuy b) { this.b = b; } //@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,rollbackFor = Spt.class) public boolean bu(int aid, int acount, int sid, int scount) throws Spt { boolean flag=false; if(1==1){ throw new Spt("error"); } boolean bs = a.abuy(aid, acount, flag); boolean b1 = b.Buystock(sid, scount, flag); if (bs&&b1){ flag=true; }else{ flag=false; } return flag; } }
先定义一下两个方法接口的对象,getset下,
方法里,用对象点出方法,通过boolean来判断是什么情况
现在开始小配置
<bean id="Buy" class="JIHE.DAO.impl.Buyimpl"> <property name="dataSource" ref="datasource"></property> </bean> <bean id="ABuy" class="JIHE.DAO.impl.ABuyimpl"> <property name="dataSource" ref="datasource"></property> </bean> <bean id="se" class="JIHE.service.impl.Buimpl"> <property name="a" ref="Buy"></property> <property name="b" ref="ABuy"></property> </bean>
两个实现类的bean,然后用service接口的实现类的bean来接收一下上面两个实现类
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///newss2228"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean id="transation" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
数据源,配置一下
记住:spring的事务处理规则,运行时异常,默认回滚
检查异常,默认提示
事务管理器 上
<bean id="trans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transation"></property>
<property name="target" ref="se"></property>
<property name="transactionAttributes">
<props>
<prop key="bu">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-Spt</prop>
</props>
</property>
</bean>
事务控制 , <prop key="bu">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-Spt</prop>
这里面是定义的策略 , 隔离级别 ,传播方式 , 异常类
REQUIRED 传播行为,开发常用,必须执行在一个事务当中
事物的传播行为表示整个事务的处理过程所跨越的业务对象将以什么样的行为参与事务 。
现在开始测试
@Test public void srt() throws Spt { ApplicationContext context=new ClassPathXmlApplicationContext("application-06.xml"); Bu trans = (Bu) context.getBean("trans"); trans.bu(1,20,1,20); }
执行的情况,就是,一边加,一边减
现在开始其他两种写法
2 注解那种
在service的实现类的方法上面加入
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,rollbackFor = Spt.class)
增加事务的隔离级别,传播方式,以及可能遇到的异常类-rollbackFor
小配置,加入一行即可
<!--<tx:annotation-driven transaction-manager="transation"></tx:annotation-driven>-->
transation - 事务平台管理器,其他的bean节点要加, 比如 3 个实现类的 ,不变 的
这样也能实现
3
<!--<tx:advice id="txAdvice" transaction-manager="transation">-->
<!--<tx:attributes>-->
<!--<tx:method name="bu" isolation="DEFAULT" propagation="REQUIRED" rollback-for="Spt"/>-->
<!--</tx:attributes>-->
<!--</tx:advice>-->
<!--<aop:config>-->
<!--<aop:pointcut id="mypoint" expression="execution(* *..JIHE.service.impl.*(..))"></aop:pointcut>-->
<!--<aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"></aop:advisor>-->
<!--</aop:config>-->
这几种都设置了异常处理的机制,在我们运行的时候,会回滚之前的运行 ,
我以上的代码,手动插入了一个异常类 , 在我们用户交完钱后就运行的异常,
这样 , 在平时运行的时候,一定是用户钱没有了, 但是,股票没有买到,这样这个方法就有了问题, 但是我们加入了
<prop key="bu">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-Spt</prop>
中途依然会报错,但是,运行的结果就发生了变化,用户的钱少了之后,如果中途方法出错,这个事务就会回滚 , 把用户的钱返还他的账户。