Spring——什么是事务?传播行为?事务隔离级别有哪些?

文章详细介绍了事务的概念,包括事务的四大特性(ACID),Spring中的事务管理方式,如编程式和声明式事务管理,特别是注解方式的使用。还深入探讨了事务的传播行为(REQUIRED,SUPPORTS等)和隔离级别(读未提交,读提交等),以及如何通过@Transactional注解来配置事务属性,如只读事务和异常回滚策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思维导图

一、什么是事务?

多条DML要么同时成功,要么同时失败

@Transaction(tx)

二、事务的四个过程:

  1. 开启事务(start transaction)

  1. 执行核心业务代码

  1. 提交事务(如果核心业务处理过程中没有出现异常)(commit transaction)

  1. 回滚事务(如果核心业务处理……出现异常)(rollback transaction)

三、事务的四个特性(ACID)是什么?

  • 原子性:不可分割,事务是最小的工作单元,

  • 一致性:事务前后总量不变,要么成功都成功,要么失败都失败

  • 隔离性:多操作之间不会产生影响就。事务和事务之间因为有隔离性,才可以保证互不干扰

  • 持久性:一个事务一旦被提交,它对数据库的数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其他有任何影响(结束的标志)

四、Spring事务管理

1、事务添加J2EE三层结构里面Service层(业务逻辑层)

2、在Spring进行事务管理操作两种方式:

①、编程式事务管理(自己写流程)

②、声明式事务管理:基于注解方式、基于xml配置文件方式

3、声明式事务管理:

基于注解方式

基于xml配置文件方式

4、在Spring进行声明式事务管理,底层使用AOP原理

5、Spring事务管理API:

PlatformTransactionManager

五、注解是什么?

@Transaction

六、可以用在哪里?

类上:类里的所有方法都添加事务

方法上:只是为方法添加事务

七、创建事务管理器

  1. 开启事务注解

  1. 在service类上面(或者service类里面方法上面)添加事务注解:@Transactional,这个注解添加到类上面,也可以添加方法上面

  1. 如果把这个注解添加类上面,这个类里面所有的方法都添加事务

  1. 如果把这个注解添加方法上面


八、事务属性

1、传播行为

传播行为是什么?

在service类中有a()方法和b()方法,a()方法上有事务,b()方法上也有事务,当a()方法执行过程中调用b()方法,事务是如何传递的?合并到一个事务里?还是开启一个新的事务?这就是事务传播行为。

①、枚举类型

事务传播行为在spring框架中被定义为枚举类型:

②、传播行为有哪些?

REQUIRED:支持当前事务,如果不存在就新建一个(默认)【没有就新建,有就加入】

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行

MANDATORY:必须运行在一个事务中,如果当前没有事务正在发生,就抛出一个异常

NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务【不支持事务,存在就挂起】

NEVER:以非事务方式运行,如果有事务存在,抛出异常【不支持事务,存在即抛异常】

NESTED:如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中,被嵌套的事务可以独立于外层事务进行提交或回滚,如果外层事务不存在,行为就像REQUIRED一样【没有事务就像和REQUIRED一样】

③、如何使用传播行为?

2、事务隔离级别

①、事务为什么要有隔离?

是为了解决多个并行事务竞争导致的数据安全性问题的一种规范

多个事务竞争可能会出现三种不同的现象:脏读、不可重复读、幻读

②、数据库中读取数据存在的三大问题:(三大读问题)

  • 脏读:读取到没有提交到的数据库的数据

  • 不可重复读:同一事务当中,第一次和第二次读取的数据不一样

  • 幻读:读到的数据是假的

—脏读

读取了还未提交的数据,然后回滚了

脏数据:还没有完全确定下来的数据

—不可重复读

指更新操作

对某个数据多次查询,但是返回了不同的结果。因为在查询间隔,被另一个事务修改并提交了

例如,一个编辑人员两次读取同一文档(如QQ或钉钉在线文档),但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题

—幻读

指增加、删除操作

读取了提交的新事务

事务A在多次读取数据的时候,另一个事务B对这个数据进行了增加或删除操作,导致事务A多次多次读取的数据不一致。

不可重复读和幻读的区别?

二者描述的则重点不同,不可重复读描述的侧重点是修改操作,而幻读描述的侧重点是添加和删除操作。


③、事务隔离级别有哪些?

  • 读未提交:read_uncommitted

  • 有脏读问题

  • 读提交:read_committed

  • 解决了脏读问题,其他事务提交之后才能督导,但存在不可重复读问题

  • 可重复读:repeatable_read

  • 解决不可重复读,可达到重复读效果,只要当前事务不结束,读取到的数据一直都是一样的,存在幻读问题

  • 序列化:serializable

  • 解决幻读问题,事务排队执行,不支持并发

3、只读事务(readOnly)

作用:spring启动优化策略

@Transactional(readOnly=true)

将当前事务设置为只读事务,在该事务执行过程中只允许select语句执行,delete、insert、update都不可执行

作用是:启动spring的优化策略,提高select语句执行效率如果该事务中确实没有增删改操作,建议设置为只读事务)

(意思是:如果事务只读的话,最好设置为只读的,意思是在告诉spring框架你可以启动自己的优化策略了,来提高select的查询效果)

4、设置哪些异常回滚事务

@Transactional(rollbackFor = RuntimeException.class)

表示当发生RuntimeException异常时就回滚事务

5、设置哪些异常不回滚事务

@Transactional(rollbackFor = NullPointerException.class)

表示当发生NullPointerException异常不回滚,其他都回滚


Spring系列文章:

Spring——是什么?作用?内容?用到的设计模式?

Spring——Bean管理-xml方式进行属性注入

Spring——Bean管理-注解方式进行属性注入

Spring——什么是IOC?

Spring——AOP是什么?如何使用?

Spring——什么是事务?传播行为?事务隔离级别有哪些?

Spring——整合junit4、junit5使用方法

如果有想要交流的内容欢迎在评论区进行留言,如果这篇文档受到了您的喜欢那就留下你点赞+收藏脚印支持一下博主~

### 事务回滚机制 当应用程序抛出异常时,Spring框架能够自动触发事务的回滚操作。默认情况下,运行时异常(RuntimeException及其子类)会导致事务被标记为回滚状态;而对于受检异常,则不会自动引发回滚除非显式配置[^1]。 对于自定义逻辑中的特定条件下的手动回滚需求,可以通过`setRollbackOnly()`方法来强制执行回滚动作。此外,在AOP环境下,如果希望某些类型的异常也能引起回滚,可以在`@Transactional`注解中指定这些异常类型作为rollbackFor参数值[^2]。 ```java @Transactional(rollbackFor = {CustomException.class}) public void methodThatShouldRollBackOnSpecificExceptions() { // Method implementation that may throw CustomException } ``` ### 事务隔离级别详解 SQL标准定义了几种不同的事务隔离级别以解决并发访问数据库资源时可能出现的一致性数据准确性问题: - **READ_UNCOMMITTED**: 允许读取尚未提交的数据变更,可能导致脏读、不可重复读幻象读现象。 - **READ_COMMITTED**: 只能读取已经提交的数据修改,防止了脏读的发生但仍然可能发生不可重复读幻象读。 - **REPEATABLE_READ**: 同一事务内多次查询返回相同的结果集,解决了不可重复读的问题,但在范围扫描场景下仍可能存在幻影读的情况。 - **SERIALIZABLE**: 提供最严格的隔离程度,完全杜绝了上述三种不一致性情况,代价是性能开销较大。 在Spring中设置隔离级别可通过`isolation`属性完成,该属性接受枚举形式的输入,如ISOLATION_DEFAULT表示采用底层JDBC驱动程序所支持的标准隔离等级[^3]。 ```java @Transactional(isolation = Isolation.SERIALIZABLE) public void highlyIsolatedOperation() { // Critical section requiring highest isolation level } ``` ### 事务传播行为 事务传播特性决定了多个事务性方法之间如何相互作用。以下是几种常见的传播策略: - **REQUIRED**:如果有现有事务则加入其中;如果没有就创建一个新的独立事务。这是最常见的选项,默认即为此项。 - **SUPPORTS**:若有现成事务便参与进去;否则以非事务方式继续执行。 - **MANDATORY**:必须在一个已有事务上下文中调用此方法,否则将抛出异常。 - **REQUIRES_NEW**:总是启动新事务,即使当前存在其他活动事务也会将其暂停并建立全新环境。 - **NOT_SUPPORTED**:建议不在任何事务范围内工作,如有必要会暂时挂起正在进行中的事务。 - **NEVER**:绝对不允许处于事务内部调用本函数,违反规定同样会造成错误响应。 - **NESTED**:类似于REQUIRED但是提供了更细粒度控制——它允许嵌套事务拥有自己单独的保存点以便局部失败不影响外部更大规模的操作。 通过调整`propagation`属性可以改变默认的行为模式,从而更好地适应具体应用场景的需求[^4]。 ```java @Transactional(propagation = Propagation.REQUIRED) public void typicalBusinessLogicMethod() { // Normal business logic here } @Transactional(propagation = Propagation.REQUIRES_NEW) public void criticalSectionNeedsNewTx() { // Logic needing its own transaction boundary } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小乔努力变强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值