脱离 Spring 实现复杂嵌套事务,之四(NESTED - 嵌套事务)

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

PROPAGATION_NESTED(嵌套事务)

定义:

    在当前事务上开启一个子事务(Savepoint),若是递交主事务。那么连同子事务一同递交。若是递交子事务则保存点以前的全部事务都会被递交。 学习

解释:

    所谓嵌套事务,指的就是 NESTED 行为。这一点你们要格外注意。 spa

    这是因为“嵌套事务”这个词在 Spring 以后具有了多重含义。一种是指 Spring 提供的事务控制体系中那种基于多行为的嵌套事务控制策略。另一种就是原汁原味 JDBC 提供给咱们的嵌套事务。本文所提到的嵌套事务在没有特殊说明的状况下都是指后者。 .net

    好了回归正题,何为嵌套事务? blog

    先不看定义,咱们从字面理解,所谓嵌套,是指一层套着另外一层的意思。那么真实状况是不是这样的呢?先看一下下面这张表: 接口

时间 事务1 事务2
T1 开始主事务
T2 操做1...
T3
建立事务保存点
T4 操做2...
T5
递交保存点
T6 操做3...
T7 回滚主事务

    上面这张表中列出了咱们理想的事务递交方式。咱们认为事务2递交不会影响到事务1。可是实际状况是错误的。 事务

    咱们知道事务保存点的功能有点至关于“锚标记”它的功效是在一个长长的事务中经过保存点来分割不一样的阶段。因为在标记“锚”时候是有前后顺序的,所以事务的不一样阶段也是有顺序的,这个是你们都能理解的逻辑。 ci

    另外咱们在学习数据库方面知识时候,知道在设置一个事务保存点以前一般会经过“begin tran....”开启事务,而后会经过“savepoint xxx”语句声明保存点。最后递交事务的时候经过“commit”语句递交。若是仅此而已则数据库事务会总体递交,递交的内容包含了自 commit 开始往前一直到最近的一个 commit 或者 begin tran 之间的全部内容。而commit 语句能够跟随一个参数“commit xxx”。那个参数就是再递交以前曾经设置的保存点名称。 get

    在数据库中递交一个保存点的含义是指递交操做只涉及到这个保存点以前的操做。假若我前后设置了两个保存点,而后我递交最后建立的那个保存点。那么第一个保存点以前的操做很显然也进入了数据库。由于这是保存点自己的工做性质。 it

    咱们在回到前面表格中提到的例子,当在 T5 阶段递交保存点的时候,T2 那里的操做很显然被正式保存到了数据库中。即便咱们在 T7 位置执行了回滚操做。可是依然只能影响到 T6。

    为此你们要各位注意,嵌套事务的真实特性。下面咱们看一看 NESTED 行为的定义是怎么说的。

    “在当前事务上开启一个子事务(Savepoint)”第一句就告诉咱们,事务控制使用的是保存点,因此咱们脑壳里应该有了一个先前印象。接下来“若是递交主事务,那么连同子事务一同递交”这也知足了咱们前面提到的“commit”无参数那个状况的描述。最后“若是递交子事务则一部分主事务也会跟随递交。”这句话偏偏就是再说咱们上面刚刚提到的内容。

具备 Savepoint 特征的事务

    呵呵,至此为止咱们已经接触到了“引用计数”、“Suspent”、“new状态”三个状态。今天再向你们介绍一种状态叫“Savepoint”至此咱们已经接触到了实现复琐事务控制中全部关键的状态。

    我发誓,后面还有一些状态会介绍给你们,可是请相信我。除了上面这四个状态比较复杂以外,其它的状态都很简单了。不信的话你们能够继续关注本文。

    当事务管理器建立事务状态时,当前链接须要建立一个Savepoint给事务状态。这时候事务状态就具有了“Savepoint特征”。

    与具备“new特征”同样,“Savepoint特征”也会协助事务管理器处理 commit & rollback 操做。

工做原理

启动事务

    与前几个行为同样 NESTED 行为在启动事务的时候会判断当前链接是否存在事务。若是存在事务则安插锚点,并设置“Savepoint特征”。若是不存在事务就启动事务(咱们知道此时当前链接正好知足“new特征”)。

    因而可知,“new特征”和“Savepoint特征”是一个彼此排斥的状况。这在后面实现的时候会大大减小不少工做。

事务中的数据库操做

    此时此刻,能够直接使用 Connection 接口畅快的使用数据库操做。因为每次进行数据库操做都要反复的申请和释放数据库链接。这会反复的使引用计数 +1,-1。 ------“这一过程当中使用的数据库链接都是新的链接”。

递交/回滚事务

    在启动事务阶段提到过,“Savepoint特征”和“new特征”是互斥的,所以在执行递交回滚的时候。须要先判断是否具备“Savepoint特征”,若是有就释放保存点这样就知足了嵌套事务的要求。 不然就继续判断“new”特征。

相关文章
相关标签/搜索