当前位置:网站首页 > Go语言开发 > 正文

spring入门(spring入门程序开发实验结果分析)



由于事务的源码和前篇的Aop源码逻辑很类似,所以本篇中某些内容不会展开去讲解,建议先阅读完全集目录中的Aop部分,再来阅读本文会更好理解。

在Spring源码深度解析:十八、事务实现② - ProxyTransactionManagementConfiguration中,解析了关事务的代理创建过程。但是由于篇幅限制,对于事务的创建还没有具体描述,本文来分析一下Spring 事务的创建过程。

需要注意的是:本文虽然叫做事务的创建,但是实际上是 Spring 针对事务开启的一些准备工作(如,事务挂起、事务创建、将事务的提交由自动提交改为手动提交等),真正的事务开启是在Sql执行时。

首先我们先来了解几个类,以便方便后面分析。

中使用保存了在不同线程中不同事务的信息。

我们从上面的部分代码可以看到,中保存的是各个线程中的事务信息。

如果有不了解 事务传播属性的,也可以先移步观看 事务特性原理及其原理、隔离级别和传播属性,否则后面的判断可能不好理解。

这里解释一下和的区别:

详细代码如下:

这里我们可以看到其基本逻辑如下:

  1. 使用封装传入的实例。对于传入的类型的参数,当前实际类型是 ,是由获取事务属性时生成的,主要用于数据承载,而这里之所以使用进行封装,也是为了提供更多的功能。
  2. 获取事务。即,事务处理的核心当然是事务,这里获取到了事务。实际上方法返回的是(实现类是 )。是对事务的进一步封装,包含了当前事务信息、挂起事务信息(如果有),保存点等信息。
  3. 构建事务信息。即。对上面几个步骤获取的信息构建并返回。是 更进一步的封装。

我们来详细看看几个类的具体内容:

  1. 关于事务管理器 ,不管是JPA还是JDBC等都实现自接口 如果你添加的是依赖,框架会默认注入实例。如果你添加的是依赖,框架会默认注入实例。
  2. (实际上的实现是) 里面包含的内容:

    这里注意实际上保存了是挂起的上层事务的信息。如果没有上层事务(也就是没嵌套事务),就是null,这里是通过(事务传播属性是) 调用(事务传播属性是) 的方式挂起来了一个来自 方法的事务信息。 只有在内嵌事务的隔离级别是才有可能会保存。




  3. 里面包含的内容:

    可以看到 是等属性更进一步封装




  4. 关于事务挂起封装成的SuspendedResourcesHolder。

    了解完上述一些类的保存内容后,下面我们来详细分析中的几个方法




实际上调用的是 方法,在这里面获取了事务(可能是创建新事物,也可能不是),返回的类型是。

下面我们来看看其代码:

可以看到基本逻辑如下:

  1. 获取事务 : 这里使用的是。创建基于JDBC 的事务实例。如果当前线程存在关于的连接,那么直接使用。这里有对保存点的一个设置,是否 开启允许保存点取决于是否设置了允许嵌入式事务。
  2. 如果当前线程存在事务,则转向嵌套事务的处理
  3. 进行事务超时设置的验证
  4. 如果传播属性是。但是当前线程又不存在事务,则抛出异常
  5. 如果传播属性是 、 都需要新建事务,通过 开始事务构建
  6. 不满足上述传播属性,则使用来进行事务构建
    对于一些隔离级别、timeout等功能的设置并不是Spring完成的,而是委托给底层的数据库连接去做的。

基于上面的逻辑我们再展开看一些方法:

1.1 doGetTransaction();

1.2 isExistingTransaction(transaction)

的实现是 中。其作用是判断当前线程是否存在事务,判断依据是当前线程记录的数据库连接不为空,且连接()中的 属性为true 。

1.3 handleExistingTransaction(def, transaction, debugEnabled);

的实现在 中,这里是为了处理嵌套事务,也就是说进入这一步则说明当前线程已经存在了事务。

这里面主要还是根据传播属性的不同而进行不同的逻辑处理。代码如下:

需要注意的是:

  • 对于传播属性,其表示当前方法必须要在他自己的事务中运行,一个新的事务被启动,所以原先的事务会被先挂起(suspend),挂起后作为当前事务 的一个属性()存在。当当前事务执行结束后,再将原事务还原。
  • 对于传播属性,由于其需要的并非是全新的事务,而且当前事务的子事务。Spring考虑了两种情况
    1、Spring中允许嵌套事务的时候,则首选设置保存点的方式作为异常处理的回滚。
    2、对于其他方式,比如 JTA 无法使用保存点的方式,那么处理方式和 相同,一旦出现异常,则由spring的事务异常处理机制去完成后续操作




1.4 suspend(null);

调用的是内容。其主要作用是为了记录原有事务的状态,便于后续操作对事务的恢复,实际上是将原事务的信息封装成 ,作为的一个属性存在。(我们这里的空挂起直接会返回null, 其他情况则会返回一个正常的)。

代码基本逻辑如下:

  1. 记录原事务信息
  2. 清除原事务信息
  3. 将原事务信息封装成返回,以便于外界恢复事务时使用

其代码如下:

1.5 startTransaction(def, transaction, debugEnabled, suspendedResources);

的实现在 中,主要作用是创建新的事务。

经历了上面几步处理,到达这一步的时候说明,当前已经不是嵌套事务。

我们详细看下面两个方法:

1.5.1 doBegin(transaction, definition);

可以说事务是从这个函数开始的,因为在这个函数中已经开始尝试对数据库连接的获取,并在在获取数据库连接的同时,也进行了一些必要的设置的同步。

  1. 尝试获取连接。但并不是每一次都会获取新的连接,如果当前线程中的 ConnectionHolder 已经存在,则没必要再次获取,或者对事物同步表示设置为true的需要重新获取连接。
  2. 设置隔离级别和只读标识
  3. 更改事务的默认提交设置。
  4. 如果事务属性是自动提交,那么需要改变这个设置,将操作委托给Spring来处理。
  5. 设置标志位,标识当前连接已经被事务激活。
  6. 设置过期时间
  7. 将ConnectionHolder 绑定到当前线程

我们这里额外看一下方法是如何设置隔离级别的

可以看到,在方法中并没有什么复杂的逻辑,因为其主要实现都交由更底层的 数据库API 来完成了。

1.5.2 prepareSynchronization(status, definition);

的实现在中。其目的是将事务信息记录到当前线程中,逻辑很简单,这里不再赘述。

详细代码如下:

的功能是根据需要创建事务。这里面考虑到嵌套事务的情况,并对事务的传播属性进行了相应的处理,最终处理后。返回的是一个 的值,里面封装了事务的各种信息,供给后面的回滚或者提交使用。

到此这篇spring入门(spring入门程序开发实验结果分析)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • git怎么用?(git怎么用于项目开发)2025-08-06 17:54:06
  • 现在学编程学什么语言(学编程学哪种语言)2025-08-06 17:54:06
  • 预训练语言模型pdf下载百度网盘(预训练语言模型 pdf)2025-08-06 17:54:06
  • linux 微信小程序开发工具(linux小程序编写)2025-08-06 17:54:06
  • 嵌入式驱动开发 教材(嵌入式驱动开发 教材有哪些)2025-08-06 17:54:06
  • 苹果开发者账号付款方式(苹果开发者账号付款方式不能网页支付)2025-08-06 17:54:06
  • 编程入门要学什么(编程入门要学什么语言)2025-08-06 17:54:06
  • argon是什么意思中文翻译(argos是什么意思中文翻译)2025-08-06 17:54:06
  • scores(scores nine goals什么意思)2025-08-06 17:54:06
  • windows驱动开发入门网盘(windows驱动开发视频教程)2025-08-06 17:54:06
  • 全屏图片