第5章 Spring的事务管理
5.1 Spring事务管理概述
5.11 事务管理的核心接口
在Spring的所有jar包中,有一个名spring-tx-4.3.6RELEAS的jar包,是提供事务管理的依赖包。在该包的org.springframework.transaction包中,三个核心接口文件分别是PlatformTransactionManager、TransactionDefinition和TransactionStatus
1.PlatfromTransactionManager
PlatfromTransactionManager接口是Spring提供的平台事务管理器,主要用于管理事务。有3个事务操作的方法:
TransactionStatus getTransaction( TransactionDefinition definition ):用于获取事务状态信息
void commit( TransactionStatus status ):提交事务
void rollback( Transaction status ):回滚事务
PlatformTransactionManager接口只是代表事务管理的接口,并不知道底层是如何管理事务的,具体如何管理事务则由它的实现类来完成。该接口常见的几个实现类如下:
(1)、用于配置JDBC数据源的事务管理器:
org.springframework.jdbc.datasource.DataSourceTransactionManager
(2)、用于配置Hibernate的事务管理器:
org.springframework.orm.hibernate4.HibernateTransactionManager
(3)、用于配置全局事务管理器:
org.springframework.transaction.jta.JtaTransactionManager
当底层采用不同的持久层技术时,系统只需使用不同的实现类。
2.TransactionDefinition
事务定义(描述)的对象,该对象中定义了事务规则,并提供获取事务相关信息的方法,具体如下:
String getName():获取事务对象名称
int getlsolationLevel:获取事务的隔离级别
int getPropagationBehavior():获取事务的传播行为
int getTimeout():获取事务的超时时间
boolean isReadOnly():获取事务的是否只读
传播行为:指在同一个方法中,不同操作前后所使用的事务。传播行为有很多种:
传播行为可以控制是否需要创建事务以及如何创建事务,查询不影响数据的改变,不需要事务管理;插入、更新和删除需要事务管理。如果没有指定事务的传播行为,Spring默认传播行为是REQUIRED(required)
3.TransactionStatus
TransactionStatus接口是事务的状态,它描述了某一时间点上事务的状态信息,该接口有6个方法:
void flush():刷新事务
boolean hasSavepoint():获取是否存在保存点
boolean isCompleted():获取事务是否完成
boolean isNewTransaction():获取是否是新事物
boolean isRollbackOnly():获取是否回滚
void setRollbackOnly():设置事务回滚
5.12 事务管理的方式:
传统的编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚
声明式事务管理:通过AOP技术实现的事务管理,主要思想是将事务管理作为一个“切面”代码单独编写,然后通过AOP技术将管理“切面”代码织入到业务目标类中。
5.2 声明式事务管理
5.21 基于XML方式的声明式事务
tx命名空间下提供了<tx:advice>元素来配置事务的通知(增强处理)。当使用<tx:advice>元素配置了事务的增强处理后,就可以通过编写AOP配置,让Spring自动对目标生成代理。
配置<tx:advice>元素时,通常需要指定id和transaction-manager属性。transaction-manager属性用于指定事务管理器。除此之外,还需要配置一个<tx:attributes>子元素,该子元素可以通过配置多个<tx:method>子元素来配置执行事务的细节。
转账方法编写:
/**
* 转账
* inUser:收款人
* outUser:汇款人
* money:收款金额
*/
public void transfer(String outUser, String inUser, Double money) {
// 收款时,收款用户的余额=现有余额+所汇金额
this.jdbcTemplate.update("update account set balance = balance +? "
+ "where username = ?",money, inUser);
// 模拟系统运行时的突发性问题
int i = /;
// 汇款时,汇款用户的余额=现有余额-所汇金额
this.jdbcTemplate.update("update account set balance = balance-? "
+ "where username = ?",money, outUser);
}
XML文件:
<?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-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 1.配置数据源 -->
<bean id="dataSource222"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost/spring" /> <!--连接数据库的用户名 -->
<property name="username" value="root" /> <!--连接数据库的密码 -->
<property name="password" value="****" />
</bean> <!-- 2.配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 -->
<property name="dataSource" ref="dataSource222" /> </bean> <!--3.定义id为accountDao的Bean -->
<bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl"> <!-- 将jdbcTemplate注入到AccountDao实例中 -->
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean> <!-- 4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource222" />
</bean> <!-- 5.编写通知:对事务进行增强(通知),需要编写对切入点和具体执行事务细节 -->
<tx:advice id="txAdvice123" transaction-manager="transactionManager">
<tx:attributes>
<!-- name:*表示任意方法名称,传播行为,隔离级别,是否只读-->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
</tx:attributes>
</tx:advice> <!-- 6.编写AOP,让spring自动对目标生成代理,需要使用AspectJ的表达式 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.itheima.jdbc.*.*(..))"
id="txPointCut111" />
<!-- 切面:将切入点与通知整合 -->
<aop:advisor advice-ref="txAdvice123" pointcut-ref="txPointCut111" />
</aop:config>
</beans>
测试类:获取实例,调用方法,常规操作
@Test///基于XML方式的声明式事务
public void xmlTest(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取AccountDao实例
AccountDao accountDao =
(AccountDao)applicationContext.getBean("accountDao"); // 调用实例中的转账方法
accountDao.transfer("Jack", "Rose", 100.0); // 输出提示信息
System.out.println("转账成功!");
}
5.22 基于Annotation(注解)方式的声明式事务
两个套路
1.在Spring容器中注册事务注解驱动:
<tx:annotation-driven transaction-manager="transactionManager"/>
XML文件:
<?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-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 1.配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost/spring" /> <!--连接数据库的用户名 -->
<property name="username" value="root" /> <!--连接数据库的密码 -->
<property name="password" value="17251104238" />
</bean> <!-- 2.配置JDBC模板 -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 -->
<property name="dataSource" ref="dataSource" /> </bean> <!--3.定义id为accountDao的Bean -->
<bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl">
<!-- 将jdbcTemplate注入到AccountDao实例中 -->
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean> <!-- 4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 5.注册事务管理器驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/> </beans>
2.在方法transfer()前加注解:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
方法:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public void transfer(String outUser, String inUser, Double money)
{
// 收款时,收款用户的余额=现有余额+所汇金额
this.jdbcTemplate.update("update account set balance = balance +? "
+ "where username = ?",money, inUser); // 模拟系统运行时的突发性问题
//int i = 1/0;
// 汇款时,汇款用户的余额=现有余额-所汇金额
this.jdbcTemplate.update("update account set balance = balance -? "
+ "where username = ?",money, outUser);
}
第5章 Spring的事务管理的更多相关文章
- 深入Spring:自定义事务管理
转自: http://www.jianshu.com/p/5347a462b3a5 前言 上一篇文章讲了Spring的Aop,这里讲一下Spring的事务管理,Spring的事务管理是建立在Aop的基 ...
- Spring AOP事务管理(使用切面把事务管理起来)
在<Spring Transaction 分析事务属性(事务的基本概念.配置)>基础上 http://blog.csdn.net/partner4java/article/details/ ...
- Spring的事务管理
事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...
- spring笔记--事务管理之声明式事务
事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使 ...
- Spring应用——事务管理
事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...
- spring+mybatis事务管理
spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...
- Spring高级事务管理难点剖析
1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播.Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没 ...
- CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)
JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...
随机推荐
- python 基础 ---- 面向对象
------ 面向对象的思想 三个基本特征: 封装(封装属性方法可以减少耦合)继承(可以抬高开发效率) 多态 主要包括 : 类 : 描述具有相同的属性和方法的对象的集合 变量: 类变量/ 成 ...
- 最小生成树 --- 求最小权值、MST
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37109 Accepted: 14982 Descri ...
- 原始(Prototype)模式
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型对象创建新的对象. 原型模式其实就是从一个对象创建另外一个可复制的对象,而且不需要知道任何创建的细节.(最常用的就是基于流的深复制) 原始模 ...
- 67 GC 垃圾回收机制
GC是JVM中自带的一个线程 他会不定时来堆中回收那些不再使用的对象,以释放内存 可以通过System.gc()来主动建议jvm尽快调度gc来回收垃圾 不同的平台的jvm对GC的策略是有所不同的 我们 ...
- GoF的23种设计模式之行为型模式的特点和分类(1)
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配. 行为型模式分为类行为模式和对象行为模式,前者采用继 ...
- redis字符串类型键的二进制操作
命令名称:setbit 语法:setbit key offset value 功能: 1)对key所存储的字符串值,设置或清除指定偏移量上的位(bit),位的设置或清除取决于value参数,可以是0也 ...
- 示例:在Nuget发布自己的包的步骤
原文:示例:在Nuget发布自己的包的步骤 一.目的:很多时候都在用第三方的Nuget包,现成的轮子可以减少很多工作量,同时我们也可以造轮子供自己和其他人使用,本示例主要演示如何发布dll到Nuget ...
- MFC 解决绘图时闪烁问题的一点经验
2015-05 由于作图过于复杂和频繁,所以时常出现闪烁的情况,一些防止闪烁的方法,如下: (1)将Invalidate()替换为InvalidateRect(). Invalidate()会导致整个 ...
- 来自GitHub的优秀开源项目系列
开发必看: 如何设计大型系统? 架构师技术图谱. 互联网Java工程师进阶扫盲 Java学习指南 Java工程师成神之路 有趣开源项目: 中华古诗词数据库 表情包博物馆
- 【转载】C#通过IndexOf方法获取某一列在DataTable中的索引位置
在C#中的Datatable数据变量的操作过程中,有时候需要知道某一个列名在DataTable中的索引位置信息,此时可以通过DataTable变量的Columns属性来获取到所有的列信息,然后通过Co ...