事务学习笔记二

通过Spring的事务管理框架,我们可以按照统一的编程模型来进行事务编程,不用关心数据访问技术以及具体访问什么类型的事务资源。再结合Spring的AOP框架,事务框架为我们带来了声明式事务。整个Spring的事务管理框架的设计原则是:让事务管理的关注点与数据访问的关注点相分离。在具体使用过程中:
A)业务层使用事务的抽象API进行事务界定,不需要关心事务资源是什么,由框架实现类来管理
B)数据访问层只关心数据访问API,不关心数据资源是否参加事务,有框架类来管理
我们使用事务框架的基本流程是:
public class FooService {
private PlatformTransactionManager tm;
public void serviceMethod() {
TransactionDefinition td = …?;
TransactionStatus ts =tm.getTransaction(td);
try {
// dao1.doDataAccess();
// dao2.doDataAccess();
}
catch(DataAccessException e) {
tm.rollback(ts);
throw e;
}
tm.commit(ts);
}
有了这个统一的事务管理编程模型,不管数据访问方式如何变换,事务管理实现可以岿然不动,至于声明式事务管理,也就是自然而然的事情了。
在知道了我们使用事务框架的基本使用流程后,我们来分析一下如何该框架的实现原理。首先看事务界定的核心接口:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition d) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void roolback(TransactionStatus status) throws TransactionException;
}
这是一个顶层接口,具体的事务界定策略由具体的实现类执行,针对不同的数据访问方式,Spring提供了相应的实现类。其次,我们以JDBC数据访问方式为例来实现一个具体的事务界定策略。对于层次划分清晰的应用来说,我们将事务管理放在Service层,将数据访问逻辑放在DAO层。JDBC的局部事务由同一个Connection来完成,为了保证两个DAO的数据访问方法处于同一事物中,我们通常使用connection-passing的方式,但是此方式没有很好地隔离事务管理代码与数据访问代码,并且使得DAO方法对具体的Connection类型产生依赖。经过思考,我们决定不在Service层与DAO层之间直接传递Connection,而是把整个事务对应的Connection实例存放到一个统一的地方去,无论是谁,需要使用时再从这个统一的地方获取,这样就很好地接触了事务管理代码与数据访问代码之间的直接耦合。


假如用来统一存放Connection的容器是TransactionResourceManager,那么该容器类的主要结构如下:
public class TransactionResourceManager {
private static ThreadLocal resource = new ThreadLocal();
public static Object getResource() {
return resource.get();
}
public static void bindResource(Object resource) {
resources.set(resource);
}
public static Object unbindResource() {
Object res = getResource();
resource.set(null);
return res;
}
}
可以看到,该容器类使用了ThreadLocal类来保存线程本地变量。我们的具体事务界定策略实现只需要在事务开始的时候,通过容器方法把Connection绑定到线程,然后在事务结束的时候解除绑定即可。为了在DAO层的数据访问时保证使用的是同一个Connection对象,我们的DAO层方法必须使用TransactionResourceManager来获取数据库连接并进行数据访问。经过前面一个步骤的努力,现在进行事务控制的时候,我们只需要为Service对象提供相应的PlatformTransactionManager实现类即可。但是,路上的事务管理框架依然存在如下两个主要问题:
A)如何保证PlatformTransactionManager的相应方法的调用顺序?
B)如何去除强制每个数据访问对象使用TransactionResourceManager来获取数据资源接口?
实际上,我们使用DataSourceUtils工具类来管理Connection,该类会从类似于TransactionResourceManager的类那里获取Connection资源。如果当前线程之前没有绑定任何Connection,那么使用数据访问对象的DataSource引用获取新的Connection,否则,使用绑定的那个connection。所以,在使用Spring事务管理框架时,必须通过DataSourceUtils来获取连接,而且像JdbcTemplate等类内部已经使用DataSourceUtils来管理链接了。从这里我们可以看到,Spring的事务管理与它的数据访问框架是紧密结合的。

时间: 2024-10-17 18:54:41

事务学习笔记二的相关文章

Android学习笔记二

17. 在ContentProvider中定义的getType()方法是定义URI的内容类型. 18. SQLiteDatabase类中的insert/delete/update/query方法其实也挺好用的,我在EquipmentProvider类中做了实现 19. Android专门有个单元测试项目(Android Test Project),在这个项目中,可以新建一个继承AndroidTestCase类的具体测试类来单元测试某个功能.我新建了一个AndroidTestProject项目,在

《SQL必知必会》学习笔记二)

<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语句,但是实际应用中的业务逻辑往往会非常复杂,所以会用到一些比较复杂的查询,如子查询,联合查询. 1.子查询 当一个查询是另一个查询的条件时,称为子查询.但是说到子查询又不的不说它与嵌套查询两者的区别,下面一张图来说明 下面再用一条sql语句来说明他们的关系. 其中在查询中又分为嵌套子查询和相关子查询,他们之间

马哥学习笔记二十六——MySQL主从复制

配置MySQL复制基本步骤: 一.master 1.启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2.选择一个惟一server-id server-id = {0-2^32} 3.创建具有复制权限的用户 REPLICATION SLAVE REPLICATION CLIENT 二.slave 1.启用中继日志 relay-log = relay-log relay-log-index = 2.选择一个惟一的server

马哥学习笔记二十二——高可用集群原理

HA Resource:资源 FailOver:故障转移 FailBack:故障转回 资源粘性:资源是否倾向于留在当前节点 Messaging Layer:集群服务信息层,基于UDP互相传递心跳信息,集群事务信息等 heartbeat(v1,v2,v3) heartbeat v3:heartbeat,pacemaker,cluster-glue corosync cman keepalived ultramonkey CRM:(cluster resource manager)集群资源管理器,统

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

JavaScript--基于对象的脚本语言学习笔记(二)

第二部分:DOM编程 1.文档象模型(DOM)提供了访问结构化文档的一种方式,很多语言自己的DOM解析器. DOM解析器就是完成结构化文档和DOM树之间的转换关系. DOM解析器解析结构化文档:将磁盘上的结构化文档转换成内存中的DOM树 从DOM树输出结构化文档:将内存中的DOM树转换成磁盘上的结构化文档 2.DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML属性,该属性代表该元素的"内容",即返回的某个元素的开始标签.结束标签之间的字符串内容(不包含其它

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意