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-- 如果当前没有事务,就新建一个事务.这是最常见 ...
随机推荐
- jquery中使用布尔类型数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JS 返回上一页并刷新,但不用重新加载整个页面(ajax实现)
需求 有三个页面A.B.C,点击A=>B,点击B=>C,在C中添加内容,点击确定返回到B,此时B页面需重新加载新的内容.再次点击B的返回按钮,希望返回到A而不是C. ===== 2017/ ...
- Dreamweaver_CS6安装及破解文件
资源下载地址: 链接: https://pan.baidu.com/s/1mhQ5DoO 密码: mnv3 1.下载,安装,先作为试用版安装 可能显示的页面不一样,但是就是安装试用版 2.接受许可协议 ...
- 深度解析CNN
[1]Deep learning简介 [2]Deep Learning训练过程 [3]Deep Learning模型之:CNN卷积神经网络推导和实现 [4]Deep Learning模型之:CNN的反 ...
- FCN详解
转载自:https://www.cnblogs.com/gujianhan/p/6030639.html 论文地址:https://arxiv.org/pdf/1411.4038v1.pdf 背景 C ...
- string容器的简单实现
1.业务使用main.cpp #include "pch.h" #include <iostream> int main() { mystring s1;//无参构造函 ...
- Https 客户端与服务器交互过程梳理
本文试图以通俗易通的方式介绍Https的工作原理,不纠结具体的术语,不考证严格的流程.我相信弄懂了原理之后,到了具体操作和实现的时候,方向就不会错,然后条条大路通罗马.阅读文本需要提前大致了解对称加密 ...
- HQL的使用和limit的替代
1.HQL不同于SQL,from必须是项目中table反转后对应的class的名字. 2.如何使用参数生成HQL语句: String hql = "from User where userI ...
- C++ class和struct的区别
class和struct定义类唯一的区别就是默认的访问权限. 如果我们使用struct关键字,则定义在第一个访问说明符之前的成员是public的:相反,如果我们使用class关键字,组这些成员是pri ...
- 关于README的内容
如何在开发项目的时候写出标准的README文件? 为什么要写这篇博客? 关于README的编写,这个也十分的重要,如果你觉得只是随便写写,那么你就错了:编写这部分也是相当的重要的.工欲善其事,必先利其 ...