嵌套事务

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

妖精的绣舞 提交于 2020-01-09 22:55:33
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 本文是<实现 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 行为由于出现了“挂起”这样的操作

脱离 Spring 实现复杂嵌套事务,之六(NOT_SUPPORTED

梦想与她 提交于 2019-11-28 11:05:08
本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《 实现 Spring 的事务控制,之一(必要的概念) 》文中所涉及的概念( 当前连接 、 引用计数 ),以及数据库连接的( new状态 ) PROPAGATION_NOT_SUPPORTED (非事务方式) 定义: 是指如果存在事务则将这个事务挂起,并使用新的数据库连接。新的数据库连接不使用事务。 解释: NOT_SUPPORTED 行为是 Spring 为我们带来的一种特殊的事务控制行为。在这种行为下它保证了当前对数据库的操作是相当于 autoCommit 值为 true 。 我们回顾第一篇文章中提到的银行转账业务:“A账户可以转账给B账户,银行要求能看到当前实时的正在交易的笔数”。我们曾在《 REQUIRES_NEW - 独立事务 》一文中见到过如何实现这个需求。现在我在像大家介绍如何通过 使用 NOT_SUPPORTED 行为实现同样的业务。 时间 事务1(开启事务) 事务2(非事务) T1 开始事务 T2 挂起事务 T3 记录日志... T4 恢复事务 T5 转账500元 T6 挂起事 务 T7 记录日志 T8 恢复事务 T9 递交事务 我们先看事务1,在事务1中展示的是一个完整的转账业务功能。它被一个事务所环抱,这个事务保证了转账业务的正确执行。 下面我们看一看事务2中是如何处理日志记录的

脱离 Spring 实现复杂嵌套事务,之八(MANDATORY

孤街浪徒 提交于 2019-11-28 11:04:52
本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《 实现 Spring 的事务控制,之一(必要的概念) 》文中所涉及的概念( 当前连接 、 引用计数 ),以及数据库连接的( new状态 ) PROPAGATION_MANDATORY(要求不存在事务) 定义: 如果当前有事务存在,就以事务方式执行;如果没有,就抛出异常。 解释: 解释 MANDATORY 行为是最好解释的行为之一。MANDATORY 强调了必须要有事务。这个行为与 NEVER行为工作方式一样,不同的是所判断的情况却正好是相反的。MANDATORY 行为下当前连接不具备事务,会抛出异常,这种行为一般很少使用。 工 作原理 来源: oschina 链接: https://my.oschina.net/u/1166271/blog/200959

脱离 Spring 实现复杂嵌套事务,之七(NEVER

女生的网名这么多〃 提交于 2019-11-28 11:04:37
本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《 实现 Spring 的事务控制,之一(必要的概念) 》文中所涉及的概念( 当前连接 、 引用计数 ),以及数据库连接的( new状态 ) PROPAGATION_NEVER(排除事务) 定义: 如果当前没有事务存在,就以非事务方式执行;如果有,就抛出异常。 解释: 解释 NEVER 行为是最好解释的行为之一。NEVER 强调了非事务。一旦发现有事务存在,往下连进行都不进行,直接抛出异常。至于工作原理我想就不用多介绍了把。 工 作原理 来源: oschina 链接: https://my.oschina.net/u/1166271/blog/200958

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

℡╲_俬逩灬. 提交于 2019-11-27 07:14:02
本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《 实现 Spring 的事务控制,之一(必要的概念) 》文中所涉及的概念( 当前连接 、 引用计数 ),以及数据库连接的( new状态 ) PROPAGATION_NESTED(嵌套事务) 定义: 在当前事务上开启一个子事务(Savepoint),如果递交主事务。那么连同子事务一同递交。如果递交子事务则保存点之前的所有事务都会被递交。 解释: 所谓嵌套事务,指的就是 NESTED 行为。这一点大家要格外注意。 这是由于“嵌套事务”这个词在 Spring 之后具备了多重含义。一种是指 Spring 提供的事务控制体系中那种基于多行为的嵌套事务控制策略。另外一种就是原汁原味 JDBC 提供给我们的嵌套事务。本文所提到的嵌套事务在没有特殊说明的情况下都是指后者。 好了回归正题,何为嵌套事务? 先不看定义,我们从字面理解,所谓嵌套,是指一层套着另一层的意思。那么真实情况是否是这样的呢?先看一下下面这张表: 时间 事务1 事务2 T1 开始主事务 T2 操作1... T3 创建事务保存点 T4 操作2... T5 递交保存点 T6 操作3... T7 回滚主事务 上面这张表中列出了我们理想的事务递交方式。我们认为事务2递交不会影响到事务1。但是实际情况是错误的。 我们知道事务保存点的功能有点相当于“锚标记

脱离 Spring 实现复杂嵌套事务,之一(必要的概念)

六眼飞鱼酱① 提交于 2019-11-27 07:13:47
写这篇博文的目的首先是与大家分享一下如何用更轻量化的办法去实现 Spring 那种完善的事务控制。 为什么需要嵌套事务? 我们知道,数据库事务是为了保证数据库操作原子性而设计的一种解决办法。例如执行两条 update 当第二条执行失败时候顺便将前面执行的那条一起回滚。 这种应用场景比较常见,例如银行转帐。A账户减少的钱要加到B账户上。这两个SQL操作只要有一个失败,必须一起撤销。 但是通常银行转帐业务无论是否操作成功都会忘数据库里加入系统日志。如果日志输出与账户金额调整在一个事务里,一旦事务回滚日志也会跟着一起消失。这时候就需要嵌套事务。 时间 事务 T1 开始事务 T2 记录日志... T3 转账500元 T4 记录日志... T5 递交事务 为什么有了嵌套事务还需要独立事务? 假设现在银行需要知道当前正在进行转账的实时交易数。 我们知道一个完整的转账业务会记录两次日志,第一次用以记录是什么业务,第二次会记录这个业务总共耗时。因此完成这个功能时我们只需要查询还未进行第二次记录的那些交易日志即可得出结果。 时间 事务1 事务2 T1 开始事务 T2 记录日志... T3 开始子事务 T4 转账500元 T5 递交子事务 T6 记录日志... T7 递交事务 分析一下上面这种嵌套事务就知道不会得出正确的结果,首先第一条日志会被录入数据库的先决条件是转账操作成功之后的递交事务。

脱离 Spring 实现复杂嵌套事务,之五(SUPPORTS

杀马特。学长 韩版系。学妹 提交于 2019-11-26 19:26:46
本文是<实现 Spring 的事务控制>系列文章中一篇。本文假设读者已经阅读并理解《 实现 Spring 的事务控制,之一(必要的概念) 》文中所涉及的概念( 当前连接 、 引用计数 ),以及数据库连接的( new状态 ) PROPAGATION_SUPPORTS(跟随环境) 定义: 是指 Spring 容器中如果当前没有事务存在,就以非事务方式执行;如果有就使用当前事务。 解释: SUPPORTS 行为是 Spring 事务传播属性中最简单的一种行为。SUPPORTS 行为本质上强调了“不作为”。如下图: 似乎我不需要多解释这张图后面的工作原理,大家只要记得。无论是什么行为下,开启事务和递交事务都会对当前连接的引用计数有++ -- 操作就可以了。 SUPPORTS 行为带给我们的结果是,如果当前环境中存在事务,那么就用这个环境的事务。否则就什么都不用。这种行为下不会对事务进行任何操作。 来源: oschina 链接: https://my.oschina.net/u/1166271/blog/200384