【Spring 篇】基于注解的Spring事务控制详解

news2024/11/15 19:31:58

在这里插入图片描述

嗨,亲爱的读者朋友们!欢迎来到这篇关于基于注解的Spring事务控制的博客。如果你曾为事务处理而头痛,那么这里将为你揭开事务的神秘面纱。我们将一步步深入探讨Spring事务的世界,用简单易懂的语言、充满情感色彩的文字,带你领略事务的奇妙之旅。

前言:什么是事务?

在我们踏入事务控制的舞台之前,让我们先来了解一下什么是事务。简而言之,事务是一系列操作,要么全部成功执行,要么全部失败回滚。这就好比你在玩电子游戏,要么通关,要么回到起点重新来过。在软件开发中,事务确保了数据的完整性和一致性,是我们保持代码健壮性的重要手段。

Spring事务管理初探

Spring框架为我们提供了一套强大而灵活的事务管理机制。而其中基于注解的事务控制,则是一种让我们事务处理变得轻松愉快的方式。不再需要繁琐的事务管理代码,一切都可以通过简单的注解来搞定。

让我们来看一个简单的例子,假设我们有一个银行服务类:

@Service
public class BankService {

    @Autowired
    private AccountRepository accountRepository;

    @Transactional
    public void transferMoney(String fromAccount, String toAccount, double amount) {
        // 从fromAccount扣除金额
        Account from = accountRepository.findByAccountNumber(fromAccount);
        from.setBalance(from.getBalance() - amount);
        accountRepository.save(from);

        // 向toAccount添加金额
        Account to = accountRepository.findByAccountNumber(toAccount);
        to.setBalance(to.getBalance() + amount);
        accountRepository.save(to);
    }
}

在这个例子中,通过在 transferMoney 方法上加上 @Transactional 注解,我们告诉Spring,这是一个事务性的方法。如果在方法执行期间发生异常,整个方法的操作将被回滚,保持数据的一致性。是不是感觉事务处理变得异常简单?

事务的传播行为:如何舞动事务的芭蕾

咱们来聊聊事务的传播行为。简而言之,传播行为定义了事务方法之间的关系。举个例子,假设我们有两个服务方法 A 和 B,A 调用了 B,那么事务传播行为就是规定了A和B之间的事务关系。

在Spring中,有几种常见的传播行为,比如 REQUIREDREQUIRES_NEWNESTED。让我们用一个小故事来解释这些概念。

小故事:Alice和Bob的银行冒险

有一天,Alice和Bob决定一同前往银行冒险。他们分别代表了两个服务方法 A 和 B,银行冒险就是一个大事务。让我们看看不同传播行为下的故事发展。

1. REQUIRED - 要共舞一场

Alice(方法A)和Bob(方法B)一起进入银行,决定共同完成这次冒险。如果Alice和Bob中任何一个遇到了困难(异常),整个冒险就失败,两人重新回到银行门口。这就是 REQUIRED 传播行为,他们共舞一场,遇到异常就一同失败。

@Transactional(propagation = Propagation.REQUIRED)
public void adventureWithBank() {
    aliceService.doSomething(); // Alice
    bobService.doSomethingElse(); // Bob
}
2. REQUIRES_NEW - 各自为政

Alice和Bob决定各自为政,独立进行银行冒险。无论其中一人失败,另一人都可以继续。这就是 REQUIRES_NEW 传播行为,各自为政,不受对方的事务影响。

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void aliceAdventures() {
    aliceService.doSomething(); // Alice
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void bobAdventures() {
    bobService.doSomethingElse(); // Bob
}
3. NESTED - 嵌套情感

Alice和Bob选择进行嵌套冒险,就像一个人在另一个人的故事里。如果Bob的冒险失败,他可以独立回到银行门口;但如果Alice的冒险失败,整个故事将重新开始。这就是 NESTED 传播行为,嵌套在对方的事务中。

@Transactional(propagation = Propagation.NESTED)
public void aliceAdventures() {
    aliceService.doSomething(); // Alice
}

@Transactional(propagation = Propagation.NESTED)
public void bobAdventures() {
    bobService.doSomethingElse(); // Bob
}

这些故事或许显得幼稚,但通过这种方式,你可以轻松理解不同传播行为的含义。

隔离级别:在不同舞台上的表演

事务的隔离级别是事务管理中另一个关键概念。隔离级别定义了多个事务之间的可见性和影响关系。Spring支持的隔离级别有 DEFAULTREAD_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE

我们来看一个简单的例子,通过不同的隔离级别来理解事务的表演。

小故事:隔离级别的舞台

在这个故事中,我们有两位演员,Alice和Bob,代表两个事务。银行就是事务的舞台,而不同的隔离级别就是这场表演的不同舞台设置。

1. READ_UNCOMMITTED - 公开彩排

Alice和Bob在银行里进行公开彩排,他们可以随意看到对方的动作,即使对方的动作还没有提交。这就是 READ_UNCOMMITTED 隔离级别,即一个事务可以看到另一个事务未提交的数据。

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void alicePerformance() {
    aliceService.doSomething(); // Alice
}

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void bobPerformance() {
    bobService.doSomethingElse(); // Bob
}
2. READ_COMMITTED - 隐蔽彩排

Alice和Bob进行了隐蔽的彩排,只有当对方的动作被提交后,才能看到。这就是 READ_COMMITTED 隔离级别,即一个事务只能看到另一个事务已经提交的数据。

@Transactional(isolation = Isolation.READ_COMMITTED)
public void alicePerformance() {
    aliceService.doSomething(); // Alice
}

@Transactional(isolation = Isolation.READ_COMMITTED)
public void bobPerformance() {
    bobService.doSomethingElse(); // Bob
}
3. SERIALIZABLE - 隔离彩排

Alice和Bob决定进行严格的隔离彩排,即一个事务完全看不到另一个事务的表演。这就是 SERIALIZABLE 隔离级别,即一个事务执行时,其他事务无法对相同的数据进行更新。

@Transactional(isolation = Isolation.SERIALIZABLE)
public void alicePerformance() {
    aliceService.doSomething(); // Alice
}

@Transactional(isolation = Isolation.SERIALIZABLE)
public void bobPerformance() {
    bobService.doSomethingElse(); // Bob
}

通过这个小故事,相信你对隔离级别有了更加生动的理解。

超时设置:等待表演的结束

有时候,我们可能希望限制事务的执行时间,以防止某个事务长时间占用资源。@Transactional 注解允许我们设置事务的超时时间,单位是秒。这就像是告诉演员们,你们的表演时间有限,不能一直霸占舞台。

@Transactional(timeout = 60)
public void alicePerformance() {
    aliceService.doSomething(); // Alice
}

在这个例子中,我们将 timeout 设置为60秒,表示这个事务的表演时间不得超过60秒。如果时间到了,不管表演是否结束,都要结束这场表演。

回滚控制:遇到意外,退场重演

在事务处理中,异常是一个无法避免的问题。Spring框架提供了 @Rollback 注解,用于控制事务是否回滚。默认情况下,Spring事务将在遇到运行时异常时回滚,但我们也可以通过 @Rollback 注解来手动控制回滚。

@Transactional
@Rollback(false)
public void alicePerformance() {
    aliceService.doSomething(); // Alice
}

在这个例子中,通过 @Rollback(false) 明确告诉Spring,即使在方法中抛出异常,也不要回滚事务。这种情况可能在我们需要记录异常情况但仍然希望保留部分已执行操作时有用。

读写操作的组合:舞台上的交响乐

在数据库事务中,读写操作的组合也是需要考虑的因素。Spring提供了 @Transactional 注解的 readOnly 属性,用于指定事务是否只读。

@Transactional(readOnly = true)
public List<Account> getAllAccounts() {
    return accountRepository.findAll();
}

在上述例子中,我们标注了 @Transactional(readOnly = true),表示这个事务只包含读操作,不包含写操作。这有助于提高数据库的性能,因为只读事务通常可以避免获得数据库写锁。

结语:跟着音乐的节奏,轻松驾驭事务的舞台

通过这篇博客,我们深入浅出地探讨了基于注解的Spring事务控制。从事务的概念开始,逐步介绍了 @Transactional 注解、事务的传播行为、隔离级别、超时设置、回滚控制、以及一些常见的使用场景。通过生动的小故事和实际的代码示例,相信你对Spring事务管理有了更加深刻的理解。

在这个舞台上,你不再是被事务搞得头痛的观众,而是优雅地跟着音乐的节奏,轻松驾驭着事务的舞台。希望这篇博客对于初学者来说是一次愉快的学习之旅,让你能够在事务的世界里游刃有余。如果你有任何疑问或者想要分享自己的经验,不妨在评论区留下你的足迹。让我们一起共同探索事务控制的奥秘,愉快地编写出高质量的、可靠的代码。感谢你的阅读,希望你在事务的舞台上能够畅快淋漓地表演!🎭💃

作者信息

作者 : 繁依Fanyi
CSDN: https://techfanyi.blog.csdn.net
掘金:https://juejin.cn/user/4154386571867191

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

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

相关文章

fastadmin 框架如何移除图片上传后预览中的删除按钮

在FastAdmin中&#xff0c;当我们启用了图片上传预览时&#xff0c;在预览区域会自动生成预览图和删除按钮&#xff0c;如下图&#xff1a; 如果我们想上移除掉这里的删除按钮&#xff0c;则需要启用自定义预览模板的功能。 首先我们找到视图中我们的预览容器&#xff0c;比如…

C++内存管理机制(侯捷)笔记4(完结)

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 介绍 下面是第四讲和第五讲…

STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯

概述 本教程使用是&#xff08;光明谷SUN_STM32mini开发板&#xff09; 免费开发板 在谷动谷力社区注册用户&#xff0c;打卡&#xff0c;发帖求助都可以获取积分&#xff0c;当然最主要是发原创应用文档奖励更多积分&#xff0e; (可用积分换取&#xff0c;真的不用钱&…

Mysql InnoDB行锁深入理解

Record Lock记录锁 Record Lock 称为记录锁&#xff0c;锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的&#xff1a; 当一个事务对一条记录加了 S 型记录锁后&#xff0c;其他事务也可以继续对该记录加 S 型记录锁&#xff08;S 型与 S 锁兼容&#xff09;&#xff0c;…

NAND SCA接口对性能影响有多大?

在多LUN场景下&#xff0c;SCA接口尤其有助于提高随机读取性能。通过合理安排读取命令和等待时间&#xff08;如tR&#xff09;&#xff0c;SCA接口可以在一个LUN完成读取后立即开始另一个LUN的读取操作&#xff0c;而无需等待整个DQ总线空闲&#xff0c;从而减少了延迟和提高了…

设计一个简易版的数据库路由

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

双指针问题——求只包含两个元素的最长连续子序列(子数组)

一&#xff0c;题目描述 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必…

vue前端开发自学,组件的生命周期函数介绍001

vue前端开发自学,组件的生命周期函数介绍001&#xff01;今天介绍一下&#xff0c;组件自身的生命周期函数。又叫做&#xff0c;钩子函数。可以借助于这些钩子函数&#xff0c;实现很多我们预想的效果。比如&#xff0c;在组件渲染 之前&#xff0c;就做一些特殊的操作等等。 …

什么是 CAS

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

Javaweb之SpringBootWeb案例查询部门以及前后端联调的详细解析

2.1 查询部门 2.1.1 原型和需求 查询的部门的信息&#xff1a;部门ID、部门名称、修改时间 通过页面原型以及需求描述&#xff0c;我们可以看到&#xff0c;部门查询&#xff0c;是不需要考虑分页操作的。 2.1.2 接口文档 部门列表查询 基本信息 请求路径&#xff1a;/depts …

内存卡为什么会提示格式化,内存卡提示格式化还能恢复吗

对于许多电脑用户来说&#xff0c;执行内存卡格式化操作导致数据丢失是一个常见的问题。在日常生活中&#xff0c;数据丢失的情况并不少见&#xff0c;但内存卡格式化后的数据恢复相对较难。目前&#xff0c;能够使用的方法较少&#xff0c;且成功率较低&#xff0c;但并不是没…

NAND系统性能提升常见方案

随着NAND的发展&#xff0c;针对NAND系统性能提升&#xff0c;业内目前主要的做法有以下几种方案&#xff1a; 1.提升总线频率和优化AC时序&#xff1a; 提高NAND闪存接口的工作频率可以显著加快数据传输速度。通过不断改进工艺和技术&#xff0c;缩短了信号稳定时间、降低了延…

Linux第29步_虚拟机连接(与主机断开连接)U盘选项为灰色解决方法

在WIN11中&#xff0c;虚拟机“连接(与主机断开连接)U盘”选项为灰色&#xff0c;解决方法如下&#xff1a; 1、关闭虚拟机电源&#xff0c;得到下面的界面&#xff1a; 2、根据上述提示&#xff0c;找到虚拟机所在磁盘 3、配置文件属性见下图&#xff1a; 4、使用记事本打开…

vim基本操作命令

一、vi简介 vi是“Visual interface”的简称&#xff0c;它在Linux上的地位就仿佛Edit程序在DOS上一样。它可以执行输出、删除、查找、替换、块操作等众多文本操作&#xff0c;而且用户可以根据自己的需要对其进行定制。Vi不是一个排版程序&#xff0c;它不象Word或WPS那样可以…

“具身智能”浪潮中,达闼机器人的商业化“奇点”已然到来?

当前&#xff0c;人形机器人产业正在快速发展&#xff0c;而2023年必将会是载入史册的一年。 具体来看&#xff0c;2023年&#xff0c;AI技术大爆发&#xff0c;可在语言、视觉、运动控制、降低研发成本等多方面赋能人形机器人产业发展。与此同时&#xff0c;特斯拉、波士顿动…

NAND Separate Command Address (SCA) 接口命令解读

CA output packet和CA input packet是Separate Command Address (SCA) NAND接口协议中用于命令和地址传输的关键数据结构。 CA Input Packet: 在SCA接口中&#xff0c;输入到NAND器件的命令和地址信息被组织成并行至串行转换的CA&#xff08;Command and Address&#xff09;输…

linux创建文件并分配权限

linux中对文件的定义 在Linux中&#xff0c;文件是一个具有符号名字的一组相关联元素的有序序列。文件可以包含的内容十分广泛&#xff0c;操作系统和用户都可以将具有一定独立功能的一个程序模块、一组数据或一组文字命名为一个文件。文件名是数据有序序列集合&#xff08;文…

Asp .Net Core 系列: 集成 CORS跨域配置

文章目录 什么是CORS?Asp .Net Core 中如何配置CORS?CorsPolicyBuilder类详解注册以及使用策略三种方式EnableCors 和 DisableCors 特性关于带证书与不带证书代码的实现跨源&#xff08;cross-origin&#xff09;不带请求证书(Credentials)跨源&#xff08;cross-origin&…

【国产之光】开年尝鲜——优秀的AI编码助手 Fitten Code

文章目录 前言1. 工具准备1.0 事先说明1.1 VSCode1.2 Fitten Code1.3 GitHub Copilot 2. 使用测评2.1 需求理解2.2 上下文理解 3. 总结推荐链接 开年尝鲜高质量国产AI编码助手——FittenCode 前言 2024年刚刚开局&#xff0c;清华大学 与 非十科技 就发布了全新的 VSCode AI…

H264码流进行RTP包封装

一.H264基本概念 H.264从框架结构上分为视频编码层&#xff08;VCL&#xff09;和网络抽象层&#xff08;NAL&#xff09;&#xff0c;VCL功能是进行视频编解码&#xff0c;包括运动补偿预测&#xff0c;变换编码和熵编码等功能&#xff1b;NAL用于采用适当的格式对VCL视频数据…