深入理解Spring Boot的事务注解及其实现原理

深入理解Spring Boot的事务注解及其实现原理

在现代企业级应用开发中,事务管理是一个至关重要的概念。Spring Boot 提供了强大的事务管理功能,使得开发者可以轻松地管理数据库事务。本文将详细介绍Spring Boot中的事务注解及其实现原理。

1. 什么是事务?

事务是指一组操作的集合,这些操作要么全部成功,要么全部失败。事务的四个关键特性是ACID:

  • 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成。
  • 一致性(Consistency):事务完成后,数据库必须处于一致的状态。
  • 隔离性(Isolation):一个事务的执行不应受到其他事务的干扰。
  • 持久性(Durability):事务完成后,其结果应永久保存在数据库中。
2. Spring Boot中的事务管理

Spring Boot通过Spring Framework的事务管理功能来实现事务管理。Spring提供了声明式事务管理和编程式事务管理两种方式。本文主要介绍声明式事务管理,即通过注解来管理事务。

3. 事务注解

在Spring Boot中,最常用的事务注解是@Transactional。这个注解可以应用于类或方法上,用于声明该类或方法需要事务支持。

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Transactionalpublic void createUser(User user) {// 业务逻辑}
}
4. @Transactional注解的属性

@Transactional注解提供了多个属性来控制事务行为:

  • propagation:事务的传播行为,默认值为Propagation.REQUIRED。其他选项包括REQUIRES_NEWMANDATORYNEVER等。
  • isolation:事务的隔离级别,默认值为Isolation.DEFAULT。其他选项包括READ_COMMITTEDREAD_UNCOMMITTEDREPEATABLE_READSERIALIZABLE等。
  • timeout:事务的超时时间,默认值为-1,表示没有超时。
  • readOnly:是否为只读事务,默认值为false
  • rollbackFor:指定哪些异常会导致事务回滚。
  • noRollbackFor:指定哪些异常不会导致事务回滚。
5. 事务的传播行为

传播行为定义了事务方法之间的相互关系。Spring提供了七种传播行为:

  • REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务。
  • MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
  • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • NESTED:如果当前存在事务,则创建一个事务嵌套;如果当前没有事务,则创建一个新的事务。
6. 事务的隔离级别

隔离级别定义了一个事务与其他事务之间的隔离程度。Spring支持五种隔离级别:

  • DEFAULT:使用底层数据库的默认隔离级别。
  • READ_UNCOMMITTED:允许读取未提交的数据,可能会导致脏读、不可重复读和幻读。
  • READ_COMMITTED:只能读取已提交的数据,避免脏读,但可能会导致不可重复读和幻读。
  • REPEATABLE_READ:在同一个事务中多次读取同一数据,结果是一致的,避免脏读和不可重复读,但可能会导致幻读。
  • SERIALIZABLE:最高的隔离级别,完全锁定相关数据,避免脏读、不可重复读和幻读,但性能较低。
7. 实现原理

Spring的事务管理是通过AOP(面向切面编程)实现的。@Transactional注解会触发Spring的事务管理器,事务管理器会在方法调用前后进行事务的开启、提交或回滚操作。

当一个带有@Transactional注解的方法被调用时,Spring会创建一个代理对象。代理对象会在方法调用前开启事务,在方法调用后根据方法的执行情况决定是提交事务还是回滚事务。

8. 事务管理的核心组件

Spring的事务管理主要依赖以下几个核心组件:

  • TransactionManager:事务管理器接口,定义了事务的基本操作,如开启、提交和回滚事务。
  • PlatformTransactionManagerTransactionManager的具体实现类,常见的有DataSourceTransactionManagerJpaTransactionManager等。
  • TransactionDefinition:定义事务的属性,如传播行为、隔离级别、超时时间等。
  • TransactionStatus:表示事务的当前状态。
9. 事务管理的配置

Spring Boot通过自动配置机制来简化事务管理的配置。@EnableTransactionManagement注解用于启用Spring的注解驱动的事务管理功能。

@Configuration
@EnableTransactionManagement
public class AppConfig {// 配置数据源和事务管理器
}
10. 事务切面的注册

Spring Boot在启动时会自动扫描并注册事务切面。具体步骤如下:

  1. 加载TransactionAutoConfiguration:Spring Boot会扫描spring.factories文件,加载TransactionAutoConfiguration类。
  2. 解析@EnableTransactionManagement注解TransactionAutoConfiguration类上有@EnableTransactionManagement注解,该注解会触发TransactionManagementConfigurationSelector类的加载。
  3. 加载ProxyTransactionManagementConfigurationTransactionManagementConfigurationSelector类会选择加载ProxyTransactionManagementConfiguration类,该类定义了事务切面的配置。
11. 事务切面的实现

ProxyTransactionManagementConfiguration类通过@Bean注解定义了BeanFactoryTransactionAttributeSourceAdvisorTransactionInterceptor等Bean。

  • BeanFactoryTransactionAttributeSourceAdvisor:定义了事务切面的切点和通知。
  • TransactionInterceptor:实现了事务的具体拦截逻辑。
@Bean
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionInterceptor(transactionInterceptor());return advisor;
}@Bean
public TransactionInterceptor transactionInterceptor() {TransactionInterceptor interceptor = new TransactionInterceptor();interceptor.setTransactionManager(transactionManager());interceptor.setTransactionAttributeSource(transactionAttributeSource());return interceptor;
}
12. 动态代理的生成

Spring使用AOP(面向切面编程)来实现事务管理。具体来说,Spring会为带有@Transactional注解的方法生成代理对象。代理对象会在方法调用前后插入事务管理逻辑。

  • JDK动态代理:用于代理实现了接口的类。
  • CGLIB代理:用于代理没有实现接口的类。
13. 事务拦截器的工作流程

当一个带有@Transactional注解的方法被调用时,事务拦截器会执行以下步骤:

  1. 获取事务属性:从TransactionAttributeSource中获取事务属性,如传播行为、隔离级别等。
  2. 获取事务管理器:根据事务属性获取相应的事务管理器。
  3. 开启事务:调用事务管理器的getTransaction方法开启事务。
  4. 执行目标方法:调用目标方法,即实际的业务逻辑。
  5. 提交或回滚事务:根据目标方法的执行结果,决定是提交事务还是回滚事务。如果方法执行成功,则调用commit方法提交事务;如果方法抛出异常,则调用rollback方法回滚事务。

以下是TransactionInterceptor类的简化代码:

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {// 获取目标方法和类Method method = invocation.getMethod();Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;// 获取事务属性TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);PlatformTransactionManager tm = determineTransactionManager(txAttr);// 开启事务TransactionStatus status = tm.getTransaction(txAttr);Object retVal;try {// 执行目标方法retVal = invocation.proceed();} catch (Throwable ex) {// 回滚事务completeTransactionAfterThrowing(status, ex);throw ex;}// 提交事务tm.commit(status);return retVal;}
}
14. 内部方法调用的限制

需要注意的是,Spring的事务管理是基于代理的,这意味着只有通过代理对象调用的方法才能触发事务管理逻辑。如果在同一个类中直接调用带有@Transactional注解的方法,事务管理逻辑将不会生效。这是因为内部方法调用不会经过代理对象。

15. 示例代码

以下是一个完整的示例,展示了如何在Spring Boot中使用@Transactional注解:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic void createUser(User user) {userRepository.save(user);// 其他业务逻辑}@Transactional(readOnly = true)public User getUser(Long id) {return userRepository.findById(id).orElse(null);}
}
16. 总结

通过AOP和代理机制,Spring能够在方法调用前后自动管理事务,从而简化了事务管理的复杂性。通过理解事务的底层实现原理有助于更好地使用和调试Spring的事务管理功能。

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

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

相关文章

Java项目-基于springboot框架的游戏分享系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

[ACTF2020] 新生赛]Exec1

目录 0x01命令执行 [ACTF2020 新生赛]Exec1 1、解法1 2、解法2 3、总结 3.1php命令注入函数 3.2java命令注入函数 3.3常见管道符 0x02SQL注入 [极客大挑战 2019]EasySQL1 0x01命令执行 [ACTF2020 新生赛]Exec1 1、解法1 ping本地&#xff0c;有回显&#xff0c;TTL…

红队-安全见闻篇(上)

声明 学习视频来自B站UP主 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一.编程与开发 1.后端语言学习 C语⾔&#xff1a;⼀种通⽤的…

Pytest-Bdd-Playwright 系列教程(1):从零开始教你写自动化测试框架「喂饭教程」

Pytest-Bdd-Playwright 系列教程&#xff08;1&#xff09;&#xff1a;从零开始教你写自动化测试框架「喂饭教程」 前言一、项目结构二、安装依赖三、BDD特性文件四、页面对象五、步骤定义六、测试脚本七、Pytest配置八、运行测试 前言 最近收到一些小伙伴在后台的留言&#x…

生成式AI时代的内容安全与系统构建:合合信息文档图像篡改检测创新方案

目录 一、生成式AI时代的内容安全与图像识别1.图像内容安全的重要性2.伪造文档与证件检测的应用场景3.人脸伪造检测技术 二、系统构建加速与文档解析1.TextIn文档解析平台2.TextIn文档解析输出的示例 三、合合信息的行业影响力总结 一、生成式AI时代的内容安全与图像识别 随着…

python-----函数详解(一)

一、概念及作用&#xff1a; 概念&#xff1a;由若干条语句组成语句块&#xff0c;其中包括函数名称、参数列表&#xff0c;它是组织代码的最小单元&#xff0c;完成一定的功能 作用&#xff1a;把一个代码封装成一个函数&#xff0c;一般按功能组织一段代码 目的就是为了重…

autMan奥特曼机器人-安装或更新golang依赖

autMan2.3.4及以上需要更新中间件或安装golang依赖&#xff0c;参照下列步骤&#xff1a; 一、直装版本 ssh下进入autMan文件夹下plugin/scripts下面输入以下指令&#xff1a; go get -u github.com/hdbjlizhe/middleware二、docker版本 从后台进入web终端&#xff0c;依次输入…

速盾:高防cdn的好处体现在什么地方?

随着互联网的迅猛发展&#xff0c;网络安全问题也日益受到关注。为了保护网站免受恶意攻击和DDoS攻击的影响&#xff0c;许多网站选择使用高防CDN&#xff08;Content Delivery Network&#xff09;服务。高防CDN的好处体现在以下几个方面。 首先&#xff0c;高防CDN可以有效防…

Ubuntu 上安装 Redmine 5.1 指南

文章目录 官网安装文档&#xff1a;命令步骤相关介绍GemRubyRailsBundler 安装 Redmine更新系统包列表和软件包&#xff1a;安装必要的依赖&#xff1a;安装 Ruby&#xff1a;安装 bundler下载 Redmine 源代码&#xff1a;安装 MySQL配置 Redmine 的数据库配置文件&#xff1a;…

Hudi 核心知识点详解

‌数据写入‌&#xff1a; ‌近实时写入‌&#xff1a;Hudi支持近实时写入&#xff0c;可以减少碎片化工具的使用&#xff0c;并通过CDC&#xff08;Change Data Capture&#xff09;增量导入RDBMS数据。此外&#xff0c;Hudi还限制小文件的大小和数量&#xff0c;优化存储效率…

Java开发者的成长轨迹:从入门到权威的二十年征程

在Java开发的漫长征途中&#xff0c;流传着一句耳熟能详的话&#xff1a;“三年入门&#xff0c;五年入行&#xff0c;十年精英&#xff0c;十五年专家&#xff0c;二十年权威”。这句话不仅是对Java开发者职业生涯的高度概括&#xff0c;更是对技术成长路径的一种深刻洞察。它…

Node.js:深入探秘 CommonJS 模块化的奥秘

在Node.js出现之前&#xff0c;服务端JavaScript基本上处于一片荒芜的境况&#xff0c;而当时也没有出现ES6的模块化规范。因此&#xff0c;Node.js采用了当时比较先进的一种模块化规范来实现服务端JavaScript的模块化机制&#xff0c;它就是CommonJS&#xff0c;有时也简称为C…

2024ideaUI切换和svn与git的切换,svn的安装和配置,idea集成svn ,2024-10-18日

2024-10-18日 2024的UI实在很不舒服&#xff0c;隐藏了很多按键&#xff1b; 第一步&#xff1a; 视图 -》 外观 -》 工具栏选出来&#xff1b; 结果出来&#xff1a; 运行的按键和设置的按钮 第二步 点击设置的按钮&#xff0c;选择最后一个&#xff0c;重启就行 结果 舒服&…

前端-基础CSS总结常用

1.书写位置:title 标签下方添加 style 双标签,style 标签里面书写 CSS 代码。 <title>CSS 初体验</title> <style>/* 选择器 { } */p {/* CSS 属性 */color: red;} </style><p>体验 CSS</p> <link rel="stylesheet" href=…

论文阅读(二十四):SA-Net: Shuffle Attention for Deep Convolutional Neural Networks

文章目录 Abstract1.Introduction2.Shuffle Attention3.Code 论文&#xff1a;SA-Net&#xff1a;Shuffle Attention for Deep Convolutional Neural Networks(SA-Net&#xff1a;置换注意力机制)   论文链接&#xff1a;SA-Net&#xff1a;Shuffle Attention for Deep Convo…

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置

本项目旨在学习如何快速使用 nodejs 开发后端api&#xff0c;并为以后开展其他项目的开启提供简易的后端模版。&#xff08;非后端工程师&#xff09; 由于文档是代码写完之后&#xff0c;为了记录项目中需要注意的技术点&#xff0c;因此文档的叙述方式并非开发顺序&#xff0…

九州未来亓绚亮相丽台Solution Day 2024,共建AI赋能教育新时代

在数字化浪潮席卷全球的当下&#xff0c;生成式人工智能正迅速渗透至数字世界的每一个角落&#xff0c;而AI技术的物理化应用也正成为新的趋势。10月22日&#xff0c;丽台解决方案日Solution Day 2024&#xff1a;物理AI推动行业数字变革在上海绿地外滩中心顺利举行。 大会聚焦…

SpringBoot项目整合Mybatis-MySql数据库编程

1.Mybatis-MySql 话不多说-直接上代码&#xff01; 1. 数据库编程的依赖 <!-- Mybatis整合Spring Boot的依赖项 --> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><…

报表工具怎么选?山海鲸VS帆软,哪个更适合你?

概述 在国产报表软件市场中&#xff0c;山海鲸报表和帆软这两款工具都占有一席之地&#xff0c;许多企业在选择报表工具时常常在它们之间徘徊。然而&#xff0c;随着企业对数据分析需求的不断增长和复杂化&#xff0c;如何选取一款高效、易用且性价比高的报表工具&#xff0c;…

HTML、CSS 和 JavaScript 的介绍

HTML、CSS 和 JavaScript 是网页设计的核心技术组合,以下是关于它们在网页设计中的介绍: 一、HTML(超文本标记语言) 结构基础 HTML 负责构建网页的结构和内容。它使用各种标签来定义网页的不同部分,如 <html>、<head>、<body> 等。例如,<h1> 到…