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-- 如果当前没有事务,就新建一个事务.这是最常见 ...
随机推荐
- Code Chef January Challenge 2019题解
传送门 \(div2\)那几道题不来做了太水了-- \(DPAIRS\) 一个显然合法的方案:\(A\)最小的和\(B\)所有连,\(A\)剩下的和\(B\)最大的连 算了咕上瘾了,咕咕咕 const ...
- 初探APT 攻击
作者:joe 所属团队:Arctic Shell 本文编写参考: https://www.freebuf.com/vuls/175280.html https://www.freebuf. ...
- Drupal 远程命令执行漏洞(CVE-2018-7600)
名称: Drupal 远程命令执行漏洞 CVE-ID: CVE-2018-7600 Poc: https://paper.seebug.org/578/ EXPLOIT-DB: https://www ...
- lamp-linux-1
LAMP编程之Linux(1) LAMP:Linux Apache MySQL PHP LNMP:Linux Nginx MySQL PHP WAMP:Windows Apache MySQL PHP ...
- su: Authentication failure 的解决方案
原因是:ubuntu默认不允许使用root登录,因此初始root账户是不能使用的,需要在普通账户下利用sudo权限修改root密码. 解决方案很简单:设置一个root密码就行了.注意是sudo 而不是 ...
- 为什么说 Gumroad 是一家 “失败” 的创业公司?
Gumroad 是一家 "失败" 的创业公司. 创立于 2012 年,Gumroad 是一个面向创造者的电商平台.创始人 Sahil Lavingia,一名 19 岁的少年,Pin ...
- C++实现二叉树的相应操作
1. 二叉树的遍历:先序(递归.非递归),中序(递归.非递归),后序(递归.非递归). #include <iostream> #include <string> #inclu ...
- SpringQuartz定时任务cronExpression配置
<!-- 每一个小时跑一次--> <property name="cronExpression"> <value>0 0 0/1 * * ?&l ...
- 将参数传递给ASP.NET Core 2.0中的中间件
问题 在ASP.NET Core的安装过程中,如何将参数传递给中间件? 解 在一个空的项目中添加一个POCO类来保存中间件的参数, publicclass GreetingOptions { publ ...
- java源码解析之Object类
一.Object类概述 Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解 Object的方法可以分成两类,一类是被关键字fin ...