一、Spring的事务管理

在Spring中通常可以通过以下三种方式来实现对事务的管理:

  1. 使用Spring的事务代理工厂管理事务
  2. 使用Spring的事务注解管理事务
  3. 使用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的事务管理的更多相关文章

  1. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  2. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  3. SpringMVC+MyBatis整合——事务管理

    项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...

  4. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  5. 【Java EE 学习 54】【OA项目第一天】【SSH事务管理不能回滚问题解决】【struts2流程回顾】

    一.SSH整合之后事务问题和总结 1.引入问题:DAO层测试 假设将User对象设置为懒加载模式,在dao层使用load方法. 注意,注释不要放开. 使用如下的代码块进行测试: 会报错:no sess ...

  6. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  7. Spring的事务管理

    事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...

  8. ssh简化后之事务管理

    为了能让大家更好的了解,所以今天跟大家分享整个项目.ps:ssh环境的搭建我就不一一讲解了,请大家参考 http://www.cnblogs.com/zczc1996/p/5842367.html. ...

  9. spring事务管理器设计思想(二)

    上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...

随机推荐

  1. BZOJ 1579--道路升级(DP&最短路)

    1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2206  Solv ...

  2. Lucene.Net+盘古分词器(详细介绍)

    本章阅读概要1.Lucenne.Net简介2.介绍盘古分词器3.Lucene.Net实例分析4.结束语(Demo下载)Lucene.Net简介 Lucene.net是Lucene的.net移植版本,是 ...

  3. 【表单验证】基于jQuery的高度灵活的表单验证(无UI)

    表单验证是前端开发过程中常见的一个需求,产品需求.业务逻辑的不同,表单验证的方式方法也有所区别.而最重要的是我们要清楚,表单验证的核心原则是--错误信息提示准确,并且尽可能少的打扰/干扰用户的输入和体 ...

  4. su: Authentication failure 的解决方案

    原因是:ubuntu默认不允许使用root登录,因此初始root账户是不能使用的,需要在普通账户下利用sudo权限修改root密码. 解决方案很简单:设置一个root密码就行了.注意是sudo 而不是 ...

  5. javasript 的DOM 节点操作:创建,插入,删除,复制以及查找节点

    DOM 含义: DOM 是文档对象模型(Document Object Model) 是一种基于浏览器编程的一套API 接口,我W3C 出台推荐的标准.其赋予了JS 操作节点的能力,当网页被加载时,浏 ...

  6. O01-Linux CentOS7中利用RDO部署OpenStack

    一.前言 1.RDO是红帽Red Hat 的一个开源项目,全称是RPM Distribution of OpenStack,能够帮助我们快捷部署OpenStack项目. 官方部署文档:https:// ...

  7. Python抓取远程文件获取真实文件名

    用urllib下载远程文件并转存到hdfs服务器,在下载时,下载地址中不一定包含文件名,需要从连接信息中获取. 1 file_url = request.form.get('file_url') 2 ...

  8. css的reset和常用的html标签的默认样式整理

    先看下常用的这些标签浏览器的默认样式有哪些: body{ margin: 8px;} hr{ border:1px inset; margin-top:.5em;margin-bottom:.5em; ...

  9. pyserial timeout=1 || timeout=0.01

    昨天在做串口通信时候发现,串口参数(timeout=1 || timeout=0.01)对通信的读数据竟然影响很大,代码如下: self.ser = serial.Serial(port=serial ...

  10. 关闭MAC特效

    Launchpad首先打开"终端"(Finder->应用程序->实用工具->终端),并且输入以下命令:defaults write com.apple.dock ...