搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
从前慢现在也慢
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
浏览器域名解析步骤_chrome浏览器解析域名的次序
2
解决npm一直停在"checking installable status"的问题
3
python卷积神经网络库_GitHub - thesouther/cnn_with_numpy: 卷积神经网络(Convolutional Neural Networks, CNN),只使用pyth...
4
Linux 添加gcc/g++的搜索路径(环境变量)_g++ 动态库查找路径 环境变量
5
Python机器学习:_python epoch
6
php https 改为 http,PHP http与https之间互转_PHP教程
7
android studio 健身软件,基于Android的健身助手设计与实现.doc
8
一文详解四种经典限流算法,面试必备。_滑动窗口限流实现
9
ThingsBoard——Android APP安装_thingsboard app
10
HTTP协议
当前位置:
article
> 正文
Spring @Transactional工作原理
作者:从前慢现在也慢 | 2024-03-12 19:10:32
赞
踩
transactional工作原理
原文地址:http://www.importnew.com/12300.html
本文将深入研究Spring的事务管理。主要介绍@Transactional在底层是如何工作的。之后的文章将介绍:
propagation(事务传播)和isolation(隔离性)等属性的使用
事务使用的陷阱有哪些以及如何避免
JPA和事务管理
很重要的一点是JPA本身并不提供任何类型的声明式事务管理。如果在依赖注入容器之外使用JPA,事务处理必须由开发人员编程实现。
1
2
3
4
5
6
7
8
9
10
11
12
UserTransaction utx = entityManager.getTransaction();
try {
utx.begin();
businessLogic();
utx.commit();
} catch(Exception ex) {
utx.rollback();
throw ex;
}
这种方式的事务管理使事务范围可以在代码中很清晰地表达出来,但它有以下缺点:
容易出现重复代码和错误
任何错误可能产生较大的影响
错误难以调试和复现
降低了代码库的可读性
如果该方法调用了其他的事务方法如何处理呢?
使用Spring @Transactional
使用Spring @Transactional,上面的代码就简化为:
1
2
3
4
@Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}
代码更加简洁,可读性更好,也是目前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注入的常用方法是:
1
2
@PersistenceContext
private EntityManager em;
这里默认为“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。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class EntityManagerFactoriesConfiguration {
@Autowired
private DataSource dataSource;
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean emf = ...
emf.setDataSource(dataSource);
emf.setPackagesToScan(
new String[] {"your.package"});
emf.setJpaVendorAdapter(
new HibernateJpaVendorAdapter());
return emf;
}
}
下一步实现配置事务管理器和在@Transactional注解的类中应用事务的切面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
@EnableTransactionManagement
public class TransactionManagersConfig {
@Autowired
EntityManagerFactory emf;
@Autowired
private DataSource dataSource;
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager tm =
new JpaTransactionManager();
tm.setEntityManagerFactory(emf);
tm.setDataSource(dataSource);
return tm;
}
}
注解@EnableTransactionManagement通知Spring,@Transactional注解的类被事务的切面包围。这样@Transactional就可以使用了。
总结
Spring声明式事务管理机制非常强大,但它可能被误用或者容易发生配置错误。
当这个机制不能正常工作或者未达到预期运行结果等问题出现时,理解它的内部工作情况是很有帮助的。
需要记住的最重要的一点是,要考虑到两个概念:事务和持久化上下文,每个都有自己不可读的明显的生命周期。
下一篇文章将介绍事务注解的常见陷阱以及如何避免。
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/225448
推荐阅读
article
spring
boot
大学
毕业
设计
管理系统
毕业
设计
源码030945_sprint
boot
毕业
相间...
本论文主要论述了如何使用java语言开发一个
spring
boot
大学
毕业
设计
管理系统
,本系统将严格按照软件开发流程进行各...
赞
踩
article
java
企业
工程
管理
系统软件
源码+
Spring
Cloud +
Spring
Boot +二次开发...
二、
企业
通过数字化转型,不仅有利于优化业务流程、提升经营
管理
能力和风险控制能力,还可强有力地促进
企业
体制机制的全面创新。...
赞
踩
article
[
Spring
Boot
] 集成
Nacos
...
Spring
Boot
3.0已发布许久,但是大多数公司的项目相关
Spring
Boot
版本仍停留在
Spring
...
赞
踩
article
Spring
Boot
与
Spring
Boot
MVC
:构建
现代化
Web
应用
的利器...
Spring
Boot
简化了项目的搭建和配置过程,而
Spring
MVC
则提供了丰富的
Web
开发功能。
Spring
Bo...
赞
踩
article
【
Spring
】
AOP
进阶-
JoinPoint
和
Proceeding
JoinPoint
详解...
在
Spring
AOP
中,
JoinPoint
和
Proceeding
JoinPoint
都是关键的接口,用于在切面中获取方法...
赞
踩
article
Netty
的
使用
-
spring
boot
整合篇_
spring
boot
netty
...
1、什么是
Netty
?
Netty
是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。N...
赞
踩
article
Spring
Boot
整合
Netty
登录、
心跳
、
自定义
编解码、重连_
springboot
+ n...
什么是
Netty
?
Netty
是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的...
赞
踩
article
Spring
Boot
整合
Netty
服务_springboot
netty
...
Spring
Boot
整合
Netty
服务_springboot
netty
springboot
netty
...
赞
踩
article
32
、
Redis
7系列:
Spring
Boot
集成
Redis
...
32
、
Redis
7系列:
Spring
Boot
集成
Redis
32
、
Redis
7系列:
Spring
Boot
集成Red...
赞
踩
article
spring
boot
和
netty
整合_
spring
boot
整合natty...
学习了
netty
的所有技术,现将
netty
和
spring
boot
进行整合_
spring
boot
整合nattyspri...
赞
踩
article
前后
端分离
SpringBoot
整合
SpringSecurity
权限控制(动态拦截
url
)_
前后
端分...
前后
端分离
SpringBoot
整合
SpringSecurity
权限控制Spring Security是一个功能强大且可...
赞
踩
article
微
服务
概述、微
服务
框架对比(
SpringCloud
与
Dubbo
)_
grpc
spring
cloud
...
什么是微
服务
? 目前的微
服务
并没有一个统一的标准,一般是以业务来划分 将传统的一站式应用,拆分成一个个的
服务
,彻底去耦合...
赞
踩
article
77
、
Spring
、
Spring
Boot
和
Spring
Cloud
的关系...
77
、
Spring
、
Spring
Boot
和
Spring
Cloud
的关系77
、
Spring
、
Spring
Boot
和S...
赞
踩
article
【
Spring
】
20
解析
Spring
注解
驱动
的
容器
配置
...
综上所述,
Spring
框架提供了丰富
的
配置
方式,
注解
驱动
的
容器
配置
和 XML
配置
各有优劣。选择哪种方式更取决于开发者...
赞
踩
article
Spring
boot
与
Spring
cloud
之间
的
关系_spring
boot
和springcl...
1、
Spring
boot
是
Spring
(AOP和IOC)
的
一套快速配置脚手架,可以基于spring
boot
快...
赞
踩
article
Spring
Boot
和
Spring
Cloud
版本
选择_
springboot
2.3.5.re...
Spring
Boot
的
版本
以数字表示例如:
Spring
Boot
2.2.5.RELEASE --> 主
版本
.次
版本
....
赞
踩
article
Spring
Boot
入门知识_
spspringboot
...
什么是
Spring
Boot
?
Spring
Boot
是由Pivotal团队提供的全新框架,其设计目的是用来简化新 S...
赞
踩
article
spring
boot
集成
Elasticsearch
7.16
.3...
spring
boot
集成
Elasticsearch
7.16
.3的使用
spring
boot
集成Elasticsear...
赞
踩
article
UWB
高精度
人员
定位
系统源码,微服务+
java
+
spring
boot+ vue+ mysql技术...
工厂
人员
定位
系统是指能够对工厂中的
人员
、车辆、设备等进行
定位
,实现对
人员
和车辆的实时监控与调度的系统,是智慧工厂建设中必...
赞
踩
article
Spring
报错_the
elements
[
spring
.
servlet
.
multipart
.mi...
com.sun.jersey.api.client.ClientHandlerException: java.net.C...
赞
踩
相关标签
spring boot
java
vue.js
css
mysql
spring cloud
企业工程管理系统软件源码
后端
mvc
spring
python
数据库
netty
redis
Java
Spring Security
java-ee
intellij-idea