文档章节

脱离 Spring 实现复杂嵌套事务,之三(REQUIRES_NEW - 独立事务)

哈库纳
 哈库纳
发布于 2014/02/14 18:38
字数 1310
阅读 3214
收藏 21

    本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《实现 Spring 的事务控制,之一(必要的概念)》文中所涉及的概念(当前连接引用计数),以及数据库连接的(new状态

RROPAGATION_REQUIRES_NEW(独立事务)

定义:

    如果当前存在事务则挂起当前事务,并开启一个全新的事务。新事务与已存在的事务之间彼此没有关系。

解释:

    REQUIRES_NEW 行为强调了独立性。它保证了每个事务状态管理范围内锁使用的数据库连接是彼此不一样的。例如独立事务会满足“A事务中存在B事务,当B事务递交的时候不影响A事务。A,B两个事务之间不存在相互关联关系。“

时间 事务1 事务2
T1 开始事务
T2 操作1...
T3
开始事务
T4 操作2...
T5 递交事务
T6
回滚事务

    定义中提到”挂起事务“这句话怎么理解?

    所谓“挂起”指的是将当前线程使用的数据库连接,暂时保存起来不在使用。取而代之的是一个新的数据库库连接。

    与挂起相对应的还有一个“恢复事务”,它们的操作是成对出现的。恢复就是将当前数据库连接释放掉,然后将以前挂起的那个数据库连接重新设为当前数据库连接。

   REQUIRES_NEW 行为由于出现了“挂起”这样的操作,因此它也带来了一个全新的事务状态叫“Suspent”。

具有 Suspent 特征的事务

    首先,Suspent 特征只会出现在两种重播行为中

  • 独立事务(REQUIRES_NEW)

  • 非事务方式(NOT_SUPPORTED)

    现在让我们看一看具有 Suspent 特征的事务究竟有什么特殊的。首先要想产生 Suspent 特征需要满足下面这样的条件。

  • 当前事务状态中不具备“new”特征

    在第一篇文章中介绍过,new状态是“标记当事务管理器创建新的事务状态时,当前连接的事务状态是如何的”。

    我们一瞧便知道,凡是不满足new状态条件的那么就只有一种可能了。在事务管理器创建事务对象的时候,当前连接已经开启了事务。这也难怪,因为独立事务的定义中第一句话就明白的写着:“如果当前存在事务则挂起当前事务”。

    我们再往下看“并开启一个全新的事务”这句话怎么解释?

    这句话的前一句已经告诉我们,如果存在事务就会挂起,然后在执行开启新事务。这是由于挂起事务之后,事务管理器会重新为我们申请一个新的数据库连接。这个连接由于还尚未开启数据库事务,因此需要开启。

工作原理

开启事务

    事务管理器在创建 REQUIRES_NEW 行为事务时,会取得当前连接这一过程会持有当前连接(引用计数+1)。注意:此时持有的数据库连接并不一定是最终在操作阶段使用的数据库连接

    然后通过判断当前连接是否存在事务状态,来决定是否通过 执行挂起事务操作。一旦执行了挂起事务的操作就相当于清空了当前的数据库连接。所以接下来需要重新申请一个数据库连接,新申请的数据库连接事务管理器也会持有它(引用计数+1)。

    接下来随后会通过 doBegin 方法为这个新连接开启事务,而这个新的连接恰恰满足了“new”状态特征。因此 REQUIRES_NEW 行为事务中的事务状态是具备“new”状态的。但要注意,这个new状态指的是当前连接,也就是后申请的那个数据库连接事务状态。

事务中的数据库操作

    无论在开启事务的时候Connection 此时此刻,可以直接使用 Connection 接口畅快的使用数据库操作。由于每次进行数据库操作都要反复的申请和释放数据库连接。这会反复的使引用计数 +1,-1。

递交/回滚事务

   在 REQUIRED 行为中我们知道,凡是具有 new 状态的事务。在最后执行 commit & rollback 动作时都会真实的去执行它们。

   但是在 REQUIRES_NEW 行为中,除了真实递交事务之外还会判断事务中是否存在“Suspent”特征。

   在前面我们知道在 REQUIRES_NEW 行为下有可能会同时持有两个数据库连接的引用,因此在 cleanupAfter 过程中虽然释放了当前连接的引用计数,但是还有一个可能存在的挂起事务还没处理。

   为此 REQUIRES_NEW 行为不同于 REQUIRES 行为的是增加了一个恢复挂起事务的过程,随后又将挂起的事务引用释放掉。

© 著作权归作者所有

哈库纳

哈库纳

粉丝 964
博文 84
码字总数 152107
作品 4
杭州
架构师
私信 提问
加载中

评论(1)

c
c340c340
讲的很好,以前对事务的传播行为以及事务之间回滚的影响总是记不清,看到对挂起以及嵌套的原理之后豁然开朗,很容易记住。看下日期居然是这么早的文章了
脱离 Spring 实现复杂嵌套事务,之一(必要的概念)

写这篇博文的目的首先是与大家分享一下如何用更轻量化的办法去实现 Spring 那种完善的事务控制。 为什么需要嵌套事务? 我们知道,数据库事务是为了保证数据库操作原子性而设计的一种解决办法...

哈库纳
2014/02/13
6.3K
14
脱离 Spring 实现复杂嵌套事务,之六(NOT_SUPPORTED - 非事务方式)

本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《实现 Spring 的事务控制,之一(必要的概念)》文中所涉及的概念(当前连接、引用计数),以及数据库连接的(n...

哈库纳
2014/02/17
9.3K
12
Spring系列之三 Spring 事务

Spring事务这个东西比之前的AOP和MVC都要复杂的多,而且Spring声明式的事务是非常常用的一个功能. 一.事务定义和并发问题 事务是指一段操作由几个部分组成,要么全完成,要不全部撤销.事务的特性...

Lubby
2015/03/28
272
0
Spring事务传播机制

概述 当我们调用一个基于Spring的Service接口方法(如UserService#addUser())时,它将运行于Spring管理的事务 环境中,Service接口方法可能会在内部调用其它的Service接口方法以共同完成一个...

rouway
2011/07/04
221
0
Spring 事务传递教程

通过这篇文章,你将学习到Spring框架中中事务的传递 1. 简介 在处理Spring管理的事务时,开发人员可以以传播的方式定义事务的行为。换句话说,开发人员能够决定业务方法如何被封装在逻辑和物...

zetaplusae
2013/10/25
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式搜索引擎的架构是怎么设计的?

业内目前来说事实上的一个标准,就是分布式搜索引擎一般大家都用elasticsearch (1) es的分布式架构原理能说一下么(es是如何实现分布式的啊) 面试官心里分析 在搜索这块,lucene是最流行的搜...

Star永恒
17分钟前
97
0
集合转数组

ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:   (1)list.toArray(); // 转换为Object类型的数组Object[] arr = list.toArray();for (...

那个猩猩很亮
21分钟前
78
0
使用canvas在前端添加水印

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" cont......

liyoungs
21分钟前
18
0
喜马拉雅音频下载工具 支持免费音频/VIP音频 文尾有彩蛋

最近流行喜马拉雅,趁你有会员,教你下载其资源 .如果没有会员可以找别人的会员获取cookie也可以.也没有别人的会员可以用此工具下载免费的音频也是不错的选择. 下载地址:https://www.90pan....

xiaogg
30分钟前
61
0
zookeeper安装(基础篇)

Zookeeper三种部署模式 1、Standalone模式,单节点部署,适合测试环境。2、伪cluster模式,单节点多实例部署,适合测试环境。3、Cluster模式,多节点集群部署,适合生产环境。 安装前准备...

丁小屁
34分钟前
35
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部