transactional注解的使用_Java:Spring @Transactional工作原理

本文将深入研究Spring的事务管理。主要介绍@Transactional在底层是如何工作的。之后的文章将介绍:

  • propagation(事务传播)和isolation(隔离性)等属性的使用
  • 事务使用的陷阱有哪些以及如何避免

JPA和事务管理

很重要的一点是JPA本身并不提供任何类型的声明式事务管理。如果在依赖注入容器之外使用JPA,事务处理必须由开发人员编程实现。

cc93282dc0673f89a2428fdd282c4741.png

这种方式的事务管理使事务范围可以在代码中很清晰地表达出来,但它有以下缺点:

  • 容易出现重复代码和错误
  • 任何错误可能产生较大的影响
  • 错误难以调试和复现
  • 降低了代码库的可读性
  • 如果该方法调用了其他的事务方法如何处理呢?

使用Spring @Transactional

使用Spring @Transactional,上面的代码就简化为:

dba5ef0d9eb54a068fe1dd79e02d936d.png

代码更加简洁,可读性更好,也是目前Spring中事务处理的推荐方式。

通过使用@Transactional,事务传播等很多重要方面可以自动处理。这种情况下如果businessLogic()调用了其他事务方法,该方法将根据选项确定如何加入正在运行事务。

这个强大机制的一个潜在缺点是它隐藏了底层的运行,当它不能正常工作时很难调试。

@Transactional含义

关于@Transactional,关键点之一是要考虑两个独立的概念,它们都有各自的范围和生命周期:

  • persistence context(持久化上下文)
  • database transaction(事务)

@Transactional本身定义了单个事务的范围。这个事务在persistence context的范围内。

JPA中的持久化上下文是EntityManager,内部实现使用了Hibernate Session(使用Hibernate作为持久化provider)。

持久化上下文仅仅是一个同步对象,它记录了有限集合的Java对象的状态,并且保证这些对象的变化最终持久化到数据库。

这是与单个事务非常不同的概念。一个Entity Manager可以跨越多个事务使用,而且的确是这样使用的。

EntityManager何时跨越多个事务?

最常见的情况是应用使用Open Session In View模式处理懒初始化异常时。

这种情况下视图层运行的多个查询处于独立的事务中,而不是单事务的业务逻辑,但这些查询由相同的entity manager管理。

另一种情况是开发人员将持久化上下文标记为PersistenceContextType.EXTENDED,这表示它能够响应多个请求。

如何定义EntityManager和Transaction之间的关系?

这由应用开发者来选择,但是JPA Entity Manager最常用的方式是“Entity Manager per application transaction”(每个事务都有自己的实体管理器)模式。entity manager注入的常用方法是:

76d04af5aacca9e57f8e1c302ae7ee0b.png

这里默认为“Entity Manager per transaction”模式。这种模式下如果在@Transactional方法内部使用该Entity Manager,那么该方法将在单一事务中运行。

@PersistenceContext如何工作?

随之而来的问题就是@PersistenceContext如何仅在容器启动时注入entity manager,假定entity manager生命周期很短暂,而且每次请求需要多个entity manager。

答案是它不能:EntityManager是一个接口,注入到spring bean中的不是entity manager本身,而是在运行时代理具体entity manager的context aware proxy(上下文感知代理)

通常用于代理的具体类为SharedEntityManagerInvocationHandler,借助调试器可以确认这一点。

那么@Transactional如何工作?

实现了EntityManager接口的持久化上下文代理并不是声明式事务管理的唯一部分,事实上包含三个组成部分:

  • EntityManager Proxy本身
  • 事务的切面
  • 事务管理器

看一下这三部分以及它们之间的相互作用。

事务的切面

事务的切面是一个“around(环绕)”切面,在注解的业务方法前后都可以被调用。实现切面的具体类是TransactionInterceptor。

事务的切面有两个主要职责:

  • 在’before’时,切面提供一个调用点,来决定被调用业务方法应该在正在进行事务的范围内运行,还是开始一个新的独立事务。
  • 在’after’时,切面需要确定事务被提交,回滚或者继续运行。

在’before’时,事务切面自身不包含任何决策逻辑,是否开始新事务的决策委派给事务管理器完成。

事务管理器

事务管理器需要解决下面两个问题:

  • 新的Entity Manager是否应该被创建?
  • 是否应该开始新的事务?

这些需要事务切面’before’逻辑被调用时决定。事务管理器的决策基于以下两点:

  • 事务是否正在进行
  • 事务方法的propagation属性(比如REQUIRES_NEW总要开始新事务)

如果事务管理器确定要创建新事务,那么将:

  • 创建一个新的entity manager
  • entity manager绑定到当前线程
  • 从数据库连接池中获取连接
  • 将连接绑定到当前线程

使用ThreadLocal变量将entity manager和数据库连接都绑定到当前线程。

事务运行时他们存储在线程中,当它们不再被使用时,事务管理器决定是否将他们清除。

程序的任何部分如果需要当前的entity manager和数据库连接都可以从线程中获取。

EntityManager proxy

EntityManager proxy(前面已经介绍过)就是谜题的最后一部分。当业务方法调用entityManager.persist()时,这不是由entity manager直接调用的。

而是业务方法调用代理,代理从线程获取当前的entity manager,前面介绍过事务管理器将entity manager绑定到线程。

了解了@Transactional机制的各个部分,我们来看一下实现它的常用Spring配置。

整合三个部分

如何将三个部分组合起来使事务注解可以正确地发挥作用呢?首先定义entity manager工厂。

这样就可以通过持久化上下文注解注入Entity Manager proxy。

6b3e7d08b7f15ce5d9033f3ef456aca5.png

下一步实现配置事务管理器和在@Transactional注解的类中应用事务的切面。

9d960fdadc9747cb1b571ed208ff6a9b.png

注解@EnableTransactionManagement通知Spring,@Transactional注解的类被事务的切面包围。这样@Transactional就可以使用了。

总结

Spring声明式事务管理机制非常强大,但它可能被误用或者容易发生配置错误。

当这个机制不能正常工作或者未达到预期运行结果等问题出现时,理解它的内部工作情况是很有帮助的。

需要记住的最重要的一点是,要考虑到两个概念:事务和持久化上下文,每个都有自己不可读的明显的生命周期。

66341644d76d4ac071bf0c1e3f2cbc83.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 2d划线 刷子_月光软件站 - 编程文档 - Java - Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO 2D GRAPHICS)...

Java 2D Graphics提供了强大的画线功能,可以控制线型,线宽,刷子的形状等,但在JDK1.2以前,没有提供这样一个功能,为了保持与旧版JDK的相容,实现一个可控制线型,线宽的画直线方法还是…

system流怎么判断为空_并行流ParallelStream中隐藏的陷阱

点击上方蓝字 ↑↑ Throwable文摘关注公众号设置星标,不定时推送高质量原创文章关注前提这篇文章介绍一下日常开发中并行流ParallelStream中隐藏的陷阱,这个问题其实离我们很近,特别是喜欢使用JDK1.8的流式编程的伙伴,应该会深有感…

vfp操作excel排序_中招计算机信息技术考试训练|Excel操作题一|排序和筛选

Excel操作题(一):进入本题工作目录,请完成以下操作。1、将单元格区域A1:F1合并后居中,字体格式设置为黑体、16号。2、将单元格区域A2:F2填充颜色改为橙色,A3:A7填充颜色改为黄色。3、用函数计算5个储蓄所的…

java 反射机制 视频_【视频笔记】Java反射机制笔记

Java 语言的反射机制在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。Java 反射…

算术溢出使用4字节值上的运算符_c语言程序设计的数据类型、运算符和表达式介绍...

数据类型 为什么在用计算机运算时,要指定数据的类型呢?在数学中,数值是不分类型的,数值的运算是绝对准确的,例如:1/3的值是0.333333(循环小数)。 而在计算机中,数据是存放在存储单元中的,它是具体存在的。而且,存储单元是由有限的字节构成的,每一个存储单元中存放数据…

java windows 下载_Windows环境下JDK的下载与安装

1.首先检查一下本机是否有安装java。按winR,在弹出窗口中输入cmd,按回车打开控制台在控制台中输入 java 并按回车,如果显示“java 不是内部或外部命令,也不是可运行的程序或批处理文件“,则说明这台电脑还没安装java可…

net应用程序中发生了未经处理的异常怎么办_介绍一些在.NET Core 3.0中引入的诊断改进工具...

编者按:即使.NET Core3.1.5已经发布,在进行.NET Core的性能诊断时,我们有时依然不知该从何处下手,那这篇介绍.NET Core3.0中引入的诊断工具,或许能为我们提供参考。在.NET Core 3.0中,我们引入了一套工具&a…

vba中有多线程吗_VBA会被Python代替吗?

先说答案:不会被替代这里引用轮子哥的话说:微软只会开发更多的增强型插件来慢慢淡化VBA,但是不会用其他语言取代VBA。早在17年底,就有风声说Python要取代VBA,成为Excel官方脚本语言。我认真翻看了下好多篇文章&#xf…

统计一个整数的所有因子的个数_【题解循环嵌套】1095:数1的个数

1095:数1的个数时间限制: 1000 ms 内存限制: 65536 KB【题目描述】给定一个十进制正整数n(1≤n≤10000),写下从1到n的所有整数,然后数一下其中出现的数字“1”的个数。例如当n2时,写下1,2。这样只出现了1个“1”;当…

运行java是提示 选择未包含 main 类型 如何解决_RuoYi 若依 代码生成器使用教程...

你好! 若是你想学习如何使用RuoYi 若依 代码生成器, 能够仔细阅读这篇文章,了解一下RuoYi 若依 代码生成器的基本知识。java新建数据表(注意字段必定要写注释)USE ry;web/*Table structure for table sys_zyq */sqlDROP TABLE IF EXISTS sys_zyq;数据库C…

vb.net 功能f8键事件_憋了三年,史上最全的 F1~F12 键用法整理出来了!

F1~F12 键在Excel表格中的用法,小编很早就想写篇教程整理一下。可三年过去了还没整理出来,原因有很多,总结成一个字:懒!这么,终于整理出来了!提示:有的电脑启用了FN键,如…

usb hid 调试软件_开源USB免驱固件升级软件分享

跳兔科技开源软件分享,免驱的USB固件升级软件,给您的产品提供无限的活力。加快产品上市速度。相信做MCU开发的人都免不了要做boot升级功能,产品投入使用中,如果再使用link进行固件更新的话就比较麻烦,那么拥有一个优秀…

yolo算法_不到2MB,超轻YOLO算法!准确率接近YOLOv3,速度快上45%

点击上方↑↑↑“OpenCV学堂”关注我来源:公众号 量子位 授权最轻的YOLO算法出来了!这是个模型非常小、号称目前最快的YOLO算法——大小只有1.3MB,单核每秒148帧,移动设备上也能轻易部署。而且,这个YOLO-Fastest算法满…

http请求丢部分数据_温故知新,HTTP/2

去年年底,据国际互联网工程任务组( IETF )消息,HTTP-over-QUIC 实验性协议将被重命名为 HTTP/3,即有望成为 HTTP 协议的第三个正式版本,也就是说HTTP/3可能要来了。 该消息是如此的惹人注目,是因为HTTP是我们身边的协议…

poi java 其他_让POI架起Java与Office之间的桥梁一

本文将阐述如何用POI来读取/写入完整的Excel文件。作者:中国IT实验室 来源:中国IT实验室 2007年8月31日本文将阐述如何用POI来读取/写入完整的Excel文件。约定:POI项目2.0版现在已经接近正式发行阶段,开发进度迅速,不断…

vue ui框架_「webAPP」记录几款比较好用的vue 移动端的ui框架

有时在做项目时,不同场景的项目既要有网站,又要有手机端,为了快速开发,如果功能简单,要求不高的话,我们一般会用H5进行移动端的适配。如果采用纯html进行书写手机端的样式,往往UI的体验感非常差…

java定义基础变量语句_编程语言第一:JAVA语言基础,变量

在前面的几篇文章中我们介绍了Java的运行环境,以及Eclipse IDE的安装与使用。从今天开始我们的文章开始介绍Java开发语言的基础知识。今天主要介绍Java变量。一、什么是变量变量是指代在内存中开辟的存储空间,用于存放运算过程中需要用到的数据。例&…

spring.profiles.active配置了没生效_微服务架构之「 配置中心 」

在微服务架构的系列文章中,前面已经通过文章《微服务架构之「服务网关 」》介绍过了在微服务中服务网关的原理和应用,今天这篇文章我们继续来聊一聊微服务中另外一个重要模块:「 配置中心 」。后面还会继续介绍 服务框架、服务监控、服务治理…

公招网报照片审核处理工具_消防员招录报名照片处理工具使用说明

消防员招录报名照片处理工具使用说明请将下载的压缩包文件全部解压后,在照片处理工具文件夹中,用鼠标双击 “消防员招录报名照片处理工具.exe” 运行照片处理工具软件。本工具是消防员招录报名照片处理专用工具,只有经本工具处理符合要求的照…

php树形数据结构是什么,数据结构 之 树

概述树的章节一般分两大部分: 一部分将树,一部分将二叉树;虽然二叉树也是树,但是二叉树足够特殊,足够有用,所以重点来讲;或者说,如果不是二叉树,树的家族也不会如此的德高…