Spring_Spring与DAO_Spring的事务管理
一、Spring的事务管理
在Spring中通常可以通过以下三种方式来实现对事务的管理:
- 使用Spring的事务代理工厂管理事务
- 使用Spring的事务注解管理事务
- 使用AspectJ的AOP配置管理事务
二、Spring事务管理API
(1)事务管理接口
1、PlatformTransactionManager接口有2个常用的实现类:
- DataSourceTransactionManager:使用JDBC或者iBatis进行持久化数据时使用;
- HibernateTransactionManager:使用Hibernate进行持久化数据时使用。
2、Spring的回滚方式
Spring事务的默认回滚方式是:发生运行时异常时回滚,发生受查异常时提交。不过对于受查异常,也可以手动设置其回滚方式。
(2)事务定义接口
A、5个事务隔离级别
B、定义了7个事务传播行为常量
- REQUIRE: 指定的方法必须在事务内执行。若当前存在事务,就加入到当前事务中,若当前没有事务,则创建一个新事务。这种传播行为也是最常见的选择,也是Spring默认的事务传播方式;
- SUPPORTS:指定的方法支持支持当前事务,但若当前没有事务,也可以以非事务方式执行;
- MANDATORY:指定的方法必须在当前事务内执行,若当前没有事务,则直接抛出异常;
- REQUIRES_NES:总是新建一个事务,若当前存在事务,就将当前事务挂起,直到新事务执行完毕;
- NOT_SUPPORTED:指定的方法不能在事务环境中执行,若当前存在事务,就将当前事务挂起‘
- NEVER:指定的方法不能在事务环境下执行,若当前存在事务,就直接抛出异常;
- NESTED:指定的方法必须在事务内执行,若当前存在事务,则在嵌套事务内执行;若当前没有事务,则创建一个新事务;
c、默认事务超时时限
三、程序举例环境搭建
购买股票举例
1、定义实体类及DB表
public class Account {
private Integer aid;
private String aname;
private double balance;// 余额 public Account() {
super();
} public Account(Integer aid, String aname, double balance) {
super();
this.aid = aid;
this.aname = aname;
this.balance = 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 double getBalance() {
return balance;
} public void setBalance(double balance) {
this.balance = balance;
} @Override
public String toString() {
return "Account [aid=" + aid + ", aname=" + aname + ", balance=" + balance + "]";
} }
Account
public class Stock {
private Integer sid;
private String sname;// 股票名称
private int count;// 股票数量 public Stock() {
super();
} public Stock(Integer sid, String sname, int count) {
super();
this.sid = sid;
this.sname = sname;
this.count = 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 int getCount() {
return count;
} public void setCount(int count) {
this.count = count;
} @Override
public String toString() {
return "Stock [sid=" + sid + ", sname=" + sname + ", count=" + count + "]";
} }
Stock
二、定义Service
public interface IBuyStockService {
void openAccount(String aname,double money);//开用户
void openStock(String sname,int amount); void buyStock(String aname,double money,String sname,int amount) throws BuyStockException;
}
IBuyStockService
import com.jmu.dao.IAccountDao;
import com.jmu.dao.IStockDao; public class BuyStockService implements IBuyStockService {
private IAccountDao adao;
private IStockDao sdao; public void setAdao(IAccountDao adao) {
this.adao = adao;
} public void setSdao(IStockDao sdao) {
this.sdao = sdao;
} @Override
public void openAccount(String aname, double money) {
// TODO Auto-generated method stub
adao.insertAccount(aname, money);
} @Override
public void openStock(String sname, int amount) {
// TODO Auto-generated method stub
sdao.insertStock(sname, amount);
} @Override
public void buyStock(String aname, double money, String sname, int amount) throws BuyStockException {
// TODO Auto-generated method stub
boolean isBuy = true;
adao.updateAccount(aname, money, isBuy); if (1 == 1) {
throw new BuyStockException("购买股票异常");
}
sdao.updateStock(sname, amount, isBuy); } }
BuyStockService
public class BuyStockException extends Exception { public BuyStockException() {
super();
// TODO Auto-generated constructor stub
} public BuyStockException(String message) {
super(message);
// TODO Auto-generated constructor stub
} }
BuyStockException
三、定义Dao
public interface IAccountDao { void insertAccount(String aname, double money);
void updateAccount(String aname, double money, boolean isBuy); }
IAccountDao
public interface IStockDao { void insertStock(String sname, int amount);
void updateStock(String sname, int amount, boolean isBuy); }
IStockDao
import org.springframework.jdbc.core.support.JdbcDaoSupport; public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao { @Override
public void insertAccount(String aname, double money) {
// TODO Auto-generated method stub
String sql = "insert into account(aname,balance) values(?,?)";
this.getJdbcTemplate().update(sql, aname, money);
} @Override
public void updateAccount(String aname, double money, boolean isBuy) {
String sql = "update account set balance=balance+? where aname=?";
if (isBuy) {
// TODO Auto-generated method stub
sql = "update account set balance=balance-? where aname=?";
}
this.getJdbcTemplate().update(sql, money,aname);
} }
AccountDaoImpl
import org.springframework.jdbc.core.support.JdbcDaoSupport; public class StockDaoImpl extends JdbcDaoSupport implements IStockDao { @Override
public void insertStock(String sname, int amount) {
// TODO Auto-generated method stub
String sql="insert into stock(sname,count) values(?,?)";
this.getJdbcTemplate().update(sql,sname,amount);
} @Override
public void updateStock(String sname, int amount, boolean isBuy) {
// TODO Auto-generated method stub
String sql="update stock set count=count-? where sname=?";
if (isBuy) {
sql="update stock set count=count+? where sname=?";
}
this.getJdbcTemplate().update(sql,amount,sname);
}; }
StockDaoImpl
四、导入Jar包
项目结构
五、使用事务代理管理事务(方法一)
<?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:context="http://www.springframework.org/schema/context"
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">
<!-- IoC --> <!--注册数据源:C3P0 -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean> <!-- 注册属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--注册Dao -->
<bean id="accountDao" class="com.jmu.dao.AccountDaoImpl">
<property name="dataSource" ref="myDataSource" /> </bean>
<bean id="stockDao" class="com.jmu.dao.StockDaoImpl">
<property name="dataSource" ref="myDataSource" /> </bean> <!-- 注册Service -->
<bean id="buyStockService" class="com.jmu.service.BuyStockService">
<property name="adao" ref="accountDao" />
<property name="sdao" ref="stockDao"/>
</bean> <!-- AOP -->
<!-- 注册事务管理器 -->
<bean id="myTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"></property>
</bean> <!-- 生成事务代理对象 -->
<bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager"></property>
<property name="target" ref="buyStockService"></property>
<property name="transactionAttributes">
<props>
<prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException </prop>
<!--
-异常:表示发生指定异常后 回滚 (通常是受查异常)
+异常:表示发生指定异常后提交 (通常是运行时异常)
-->
</props>
</property>
</bean>
</beans>
applicationContext.xml
-异常:表示发生指定异常后 回滚 (通常是受查异常)
+异常:表示发生指定异常后提交 (通常是运行时异常)
<!-- 生成事务代理对象 -->
<bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager"></property>
<property name="target" ref="buyStockService"></property>
<property name="transactionAttributes">
<props>
<prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException </prop>
<!--
-异常:表示发生指定异常后 回滚 (通常是受查异常)
+异常:表示发生指定异常后提交 (通常是运行时异常)
-->
</props>
</property>
</bean>
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.jmu.service.BuyStockException;
import com.jmu.service.IBuyStockService; public class MyTest { private IBuyStockService service; @Before
public void before(){
String resource="applicationContext.xml";
ApplicationContext aContext=new ClassPathXmlApplicationContext(resource);
service=(IBuyStockService)aContext.getBean("serviceProxy");
} @Test
public void test01(){
service.openAccount("张三", 10000);
service.openStock("腾讯", 0); }
@Test
public void test02() throws BuyStockException{
service.buyStock("张三", 2000, "腾讯", 5); } }
MyTest
六、使用注解管理事务(方法二)
Spring配置文件约束
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- AOP -->
<!-- 注册事务管理器 -->
<bean id="myTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"></property>
</bean> <!-- 注册事务注解驱动 -->
<tx:annotation-driven transaction-manager="myTransactionManager"/>
@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
@Override
public void openAccount(String aname, double money) {
// TODO Auto-generated method stub
adao.insertAccount(aname, money);
} @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
@Override
public void openStock(String sname, int amount) {
// TODO Auto-generated method stub
sdao.insertStock(sname, amount);
} @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED,rollbackFor=BuyStockException.class)
@Override
public void buyStock(String aname, double money, String sname, int amount) throws BuyStockException {
// TODO Auto-generated method stub
boolean isBuy = true;
adao.updateAccount(aname, money, isBuy); if (1 == 1) {
throw new BuyStockException("购买股票异常");
}
sdao.updateStock(sname, amount, isBuy); }
输出结果:
七、使用AspectJ的AOP配置管理事务(重点)
导入Jar包
<!-- AOP -->
<!-- 注册事务管理器 -->
<bean id="myTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"></property>
</bean> <tx:advice id="txAdvice" transaction-manager="myTransactionManager">
<!--事务属性 -->
<!--将事务属性织入到方法中 -->
<tx:attributes>
<!--这里指定的是为每一个连接点指定所要应用的事务属性 -->
<tx:method name="open*" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED"
rollback-for="BuyStockException" />
</tx:attributes>
</tx:advice> <!-- AOP配置 -->
<aop:config>
<!--这里指定的是切入点 -->
<!-- execution(* *..service.*.open*(..)) -->
<aop:pointcut expression="execution(* *..service.*.*(..))"
id="myPoint" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint" />
</aop:config>
Spring_Spring与DAO_Spring的事务管理的更多相关文章
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- spring声明式事务管理总结
事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...
- SpringMVC+MyBatis整合——事务管理
项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- 【Java EE 学习 54】【OA项目第一天】【SSH事务管理不能回滚问题解决】【struts2流程回顾】
一.SSH整合之后事务问题和总结 1.引入问题:DAO层测试 假设将User对象设置为懒加载模式,在dao层使用load方法. 注意,注释不要放开. 使用如下的代码块进行测试: 会报错:no sess ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- Spring的事务管理
事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...
- ssh简化后之事务管理
为了能让大家更好的了解,所以今天跟大家分享整个项目.ps:ssh环境的搭建我就不一一讲解了,请大家参考 http://www.cnblogs.com/zczc1996/p/5842367.html. ...
- spring事务管理器设计思想(二)
上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...
随机推荐
- docker设置引用国内镜像加速
设置步骤: 1 先到daocloud.io网站注册一个账号 过程略,注册成功后,进入控制台 2 点击控制台上的加速器 拉到中间部分,有一个『主机监控程序』的文字链接,见下图: 然后选择主机类型,我用的 ...
- C#取得控制台应用程序的根目录方法
如有雷同,不胜荣幸,若转载,请注明 取得控制台应用程序的根目录方法1:Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径2:AppDomain.Curren ...
- 「雅礼集训 2018 Day10」贪玩蓝月
题目链接 题意分析 我们考虑维护两个栈 分别支持左边的插入删除以及右边的插入删除 然后对于两两个栈的我们需要用背包求出最优答案 注意 删除时如果不够的话 我们需要从另一个栈中取出一半加入另一个栈中 注 ...
- python3的全局变量和局部变量
局部变量 定义在函数体内部的变量称为局部变量 函数的形参也是局部变量 局部变量的作用范围只在声明该局部变量的函数体内 局部变量在函数调用时被创建,在函数调用完成后自动销毁 全局变量 定义在函数体外,模 ...
- CSS--浮动(float)布局
浮动概述:浮动,指的是元素标签使用float属性.应用float属性的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止.浮动的本质是让文字围绕图片,但现在很多时候使用浮动进行布局 ...
- github访问慢加速访问
实测从1kb到了1m多 方法: 登录 https://www.ipaddress.com/ 输入github.com得到一个或两个IP地址 输入github.global.ssl.fastly.net ...
- Java 子类父类构造方法执行顺序
public class Test { class Super { int flag = 1; Super() { test(); } void test() { System.out.println ...
- 【性能测试】:LR中解决接口请求中包含中文字符,服务器不识别的问题
在LR中,直接写的接口请求,如果请求字段包含中文字段,服务器会不识别,这个时候就要用到lr_convert_string_encoding这个函数: 具体用法: lr_convert_string_e ...
- net与树莓派的情缘-安装SVN(三)
sudo apt-get install subversion cd /home/pi mkdir svn svnadmin create /home/pi/svn/Project cd /home/ ...
- 【文档】六、Mysql Binlog版本
binlog文件格式有以下几种: v1:用于3.23版本 v3:用于4.0.2到4.1版本 v4:用于5.0及以上版本 v2版本只在4.0.x版本中使用,目前已经不再支持了. 处理binlog的程序必 ...