spring-boot事务解析@Transactional

隔离级别

  1. 未提交读
    这是最低的隔离级别,这种隔离级别下,允许一个事务读取另外一个事务没有提交的数据,因此会产生脏读不可重复读欢读问题,在@Transactional中可通过isolation = Isolation.READ_UNCOMMITTED来设置此隔离级别。这种隔离级别比较危险,因此不常采用。
  2. 读已提交
    这种隔离级别,一个事务只能读取另外一个事务已经提交的数据,不能读取未提交的数据。但是如果出现第一次读和第二次读取之间存在有另一个事务提交,会导致两次读取结果不一致,也就是不可重复读现象,在@Transactional中可通过 isolation = Isolation.READ_COMMITTED 来设置此隔离级别。
  3. 可重复读
    这种隔离级别是为了解决读已提交隔离级别的缺点,即避免出现不可重复读现象,该隔离级别下,如果事务1想读取事务2之前读取过数据,那么数据库就会阻塞事务1的读取行为,只有当事务2提交之后,事务1才能读取到该数据,这就解决的不可重复读的问题。但是这也会有新的问题,那就是幻读幻读不便于理解,这里用业务场景简单记录介绍一下:事务1读取当前库存有10件,于是开始扣减库存,在下一步生成交易记录之间,这时候有一个事务2进行了交易记录的查询操作,举例来说比如事务2这时候查询到交易记录有30次,在查询交易记录结束后,事务1进行了插入刚刚交易记录的操作,并且提交事务,这时候数据库内的数据就变成了了9件库存,31次交易记录,但是事务2刚刚读取到的交易记录是30次,如果事务2将读取到的30次交易记录数据作为下一步业务的数据,那么这个数据就是错误的(比如进行统计)。这就是幻读现象。在@Transactional中可通过isolation = Isolation.REPEATABLE_READ来设置此隔离级别。
  4. 串行化
    这是数据库最高的隔离级别,要求所有的SQL按照顺序执行,可以克服上面的几种问题,但是它的性能也是最慢的。在@Transactional中可通过isolation = Isolation.SERIALIZABLE来设置此隔离级别。
  5. spring-boot配置默认的隔离级别
    通过在application文件中进行配置,可以对项目的默认隔离级别进行设置,举例如下
#tomcat数据源默认隔离级别
spring.datasource.tomcat.default-transaction-isolation=2

这个2对应的隔离级别就是读已提交,至于为什么是2,这是因为Isolation.class枚举类设置的值如此
Isolation.class

传播行为

传播行为是方法之间调用事务采取的策略问题。虽然很多情况下我们认为数据提交应该要么全部成功,要么全部失败,但是现实业务中也会存在一些允许部分失败的情况。因此,传播行为就可以对这些子方法的事务隔离级别进行设置。
Spring事务机制对数据库存在7种传播行为,是通过枚举类Propagation定义,该类定义如下:
Propagation类定义
分别含义如下:

  1. REQUIRED:需要事务,若当前存在事务,就使用当前事务,否则子方法将创建新事物。
  2. SUPPORTS:支持事务,若当前存在事务,就使用当前事务,若没有,则继续使用无事务运行子方法。
  3. MANDATORY:必须使用事务,若当前没有事务,会抛出异常,若当前存在事务,就使用当前事务。
  4. REQUIRES_NEW:无论当前事务是否存在,都会创建新事务,新事务与当前事务相互独立。
  5. NOT_SUPPORTED:不支持事务,若当前存在事务,会将事务挂起,继续执行方法。
  6. NEVER:不支持事务,如果当前存在事务,会抛出异常。
  7. NESTED:当前方法调用子方法时,若子方法发生异常,只会回滚子方法执行过的SQL,而不回滚当前方法的事务。
    常用的传播行为为:REQUIRED,REQUIRES_NEW,NESTED。

@Transactional失效情况

由于Spring数据库事务的约定,其实现原理是AOP,而AOP的原理是动态代理,因此如果是自调用情况(比如同一个Service中的方法,A调用B,那么就是自调用),而不是代理对象去调用,那么就不会产生AOP,这样Spring就不会将事务代码织入约定。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值