谈谈你对Spring 事务的理解

本质

Spring事务是基于数据库事务的隔离级别的封装,并定义了事务传播行为,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制。

所以,首先得先明确数据库中事务概念、特性、并发问题和隔离级别。

参照文章:事务的概念、特性和隔离级别以及他们解决了什么问题

Spring事务传播行为是spring为了业务层之间调用事务的关系而提出的,即数据库层面是不存在事务传播行为的。

Spring定义的传播属性和隔离级别实现:

Spring中存在7种传播属性

如果存在当前事务可分4类,

1、按照当前事务继续处理

REQUIRED如果没有事务则重新建立一个。spring默认的事务的传播;

SUPPORTS如果没有事务,就啥也不干;

MANDATORY如果当前没有事务,就抛出异常;

2、挂起当前事务

REQUIRES_NEW如果当前没有事务,新建事务,是两个独立的事务;

NOT_SUPPORTED如果当前没有事务,以非事务方式执行操作;

3、抛出异常

NEVER如果当前没有事务,以非事务方式执行。

4、嵌套在当前的事务中

NESTED如果没有活动事务,则按REQUIRED属性执行。有多个回滚点,内部事务的回滚不会对外部事务造成影响。

注意:事务失效的7种情况

1、未启用spring事务管理功能: @EnableTransactionManagement 注解用来启用spring事务自动管理事务的功能;

2、方法不是public类型的:@Transaction用在了非public方法上,事务将无效;

3、数据源未配置事务管理器:spring是通过事务管理器了来管理事务,每个数据源都要配置;

4、自身调用问题: @Transactional中有AOP的逻辑会拦截异常会导致传播事务失效,只有在代理对象之间进行调用时,才会触发切面逻辑。可以在类中注入该类代理对象,然后在嵌套的方法中调用代理对象的方法;

5、异常类型错误:默认情况下,RuntimeException和Error的情况下,spring事务才会回滚。也可以自定义回滚的异常类型,@Transactional(rollbackFor = {异常类型列表});

6、异常被吞:在方法中吞没异常;

7、业务和spring事务代码必须在一个线程中:spring事务实现中使用了ThreadLocal,要求业务代码必须和spring事务的源码执行过程必须在一个线程中,才会受spring事务的控制;

Spring中存在5种隔离级别:

springmysql多了一种default,表示使用数据库默认的事务隔离级别

Spring 事务执行流程:

spring的事务执行是由aop来实现的,首先要生成具体的代理对象,然后按照aop的整套流程来执行具体的操作逻辑,正常情况下要通过通知来完成核心功能,但是事务不是通过通知来实现的,而是通过一个TransactionInterceptor来实现的,然后调用invoke来实现具体的逻辑

具体事务执行流程:

1、先做准备工作解析方法上事务相关的属性来判断是否开始新事务

2、当需要开启的时候,获取数据库连接关闭自动提交功能,开起事务

3、执行具体的sql逻辑操作

4、在操作过程中,如果执行失败了,那么会通过completeTransactionAfterThrowing来完成事务的回滚操作,回滚的具体逻辑是通过doRollBack(con,rollback)方法来实现的,实现的时候也是要先获取连接对象,通过连接对象来回滚

5、如果执行过程中,没有任何意外情况的发生,那么通过commitTransactionAfterReturning来完成事务的提交操作,提交的具体逻辑是通过doCommit(con.commot)方法来实现的,实现的时候也是要获取连接,通过连接对象来提交

6、当事务执行完毕后通过cleanupTransactionInfo清除相关的事务信息j

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值