本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《实现 Spring 的事务控制,之一(必要的概念)》文中所涉及的概念(当前链接、引用计数),以及数据库链接的(new状态) 数据库
是指若是存在事务则将这个事务挂起,并使用新的数据库链接。新的数据库链接不使用事务。 spa
NOT_SUPPORTED 行为是 Spring 为咱们带来的一种特殊的事务控制行为。在这种行为下它保证了当前对数据库的操做是至关于 autoCommit 值为 true 。 .net
咱们回顾第一篇文章中提到的银行转帐业务:“A帐户能够转帐给B帐户,银行要求能看到当前实时的正在交易的笔数”。咱们曾在《REQUIRES_NEW - 独立事务》一文中见到过如何实现这个需求。如今我在像你们介绍如何经过使用 NOT_SUPPORTED 行为实现一样的业务。 日志
时间 | 事务1(开启事务) | 事务2(非事务) |
T1 | 开始事务 | |
T2 | |
挂起事务 |
T3 | |
记录日志... |
T4 | |
恢复事务 |
T5 | 转帐500元 | |
T6 | |
挂起事务 |
T7 | |
记录日志 |
T8 | |
恢复事务 |
T9 | 递交事务 | |
咱们先看事务1,在事务1中展现的是一个完整的转帐业务功能。它被一个事务所环抱,这个事务保证了转帐业务的正确执行。 blog
下面咱们看一看事务2中是如何处理日志记录的。 接口
首先事务2在记录日志以前挂起了当前事务,还记得前面在《REQUIRES_NEW - 独立事务》一文中提到的“挂起”操做和“Suspent特征”么? 事务
事务2在 NOT_SUPPORTED 行为下,会挂起当前事务。与 REQUIRES_NEW 行为不一样的是,它在挂起以后不会在尝试开启新的事务。也就是这一点的区别决定了 NOT_SUPPORTED 行为与 REQUIRES_NEW 行为。 ci
事务管理器在建立 NOT_SUPPORTED 行为事务时,会取得当前链接这一过程会持有当前链接(引用计数+1)。注意:此时持有的数据库链接并不必定是最终在操做阶段使用的数据库链接。 get
而后经过判断当前链接是否存在事务状态,来决定是否经过 执行挂起事务操做。一旦执行了挂起事务的操做就至关于清空了当前的数据库链接。因此接下来须要从新申请一个数据库链接,新申请的数据库链接事务管理器也会持有它(引用计数+1)。 it
不一样于 REQUIRES_NEW 行为的是,在 NOT_SUPPORTED 行为下事务管理器是不会开启新链接的事务的。也就是说当前链接是不会被标记“new”状态。它一直工做在非事务模式下。
不管在开启事务的时候Connection 此时此刻,能够直接使用 Connection 接口畅快的使用数据库操做。因为每次进行数据库操做都要反复的申请和释放数据库链接。这会反复的使引用计数 +1,-1。
最后因为不须要管理当前链接的事务,NOT_SUPPORTED 行为须要作的只有草率的处理掉当前链接。而后恢复上一个事务就能够了。