spring-boot事务解析@Transactional

spring-boot事务解析@Transactional,第1张

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

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

传播行为

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

分别含义如下:

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5712983.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存