事务隔离级别和传播行为基础篇

匿名 (未验证) 提交于 2019-12-03 00:37:01

再次之前自认为我对数据库事务和隔离级别很熟悉了,至少以前整理过,看过网上很多文章,有些带有命令行操作的印象挺深,但是事务传播(包块调用外部系统服务)、分布式锁、mybatis一级缓存等一起存在业务代码中,导致了很多看起来听不可思议的问题,这都是线上案例。

项目中架构师是否跟你说类似的话,事务最好不要嵌套,为什么?如果这样的话事务传播应如何使用,为了方便本片先将事务相关的基础知识做下汇总:

数据库事务ACID特性

1)原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2)一致性(Consistency)事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3) 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账(其实是隔离级别中的串行化)。
4)持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

事务4种隔离级别

1):Read Uncommitted 简单来说就是A读取B未提交内容(有可能回滚)【多个事务|修改操作】
2):Read Committed又叫做不可重复读(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)【同一个事务,多次读取,读取了别人提交的事务导致两次查询结果不同|修改操作】

4): Serializable(可串行化) 这是最高的隔离级别,它通过强制事务排序,并发写入后者会报错,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

数据库隔离级别网上资料太多了,有些人做了一些很有意思的实验(不是在代码中),弄两个命令行客户端,设置下隔离级别,A窗口开启事务修改,提交,B窗口读取。这种对你理解事务隔离级别还是比较有用,这里就不做过多的演示。

事务在代码中体现(给小白看的):

1) 一个事务多笔操作在,代码中就是service多次调用dao(insert、update)

2) service1有自己的dao同时又调用service2,service2也有dao操作,但是它们都是在同一个线程内,这样就导致了事务传播【service嵌套】。

3)service嵌套了之后内部事务失败,外部要如何处理,或者外部失败了内部如何处理,这就是靠事务传播行为来控制了。

事务7种传播行为

传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

PROPAGATION_NESTED和PROPAGATION_REQUIRES_NEW【作用在内层service】看起来很相似都是外层没有就创建一个事务,却别在于前者是独立的事务,跟外层传播行为无关,外层爱咋地咋地,内部不受影响。而后者受外层影响,外层抛出异常,内层也会回滚。

我工作中只用过三种,PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED
先不管抛出异常的类型 rollbackFor=RuntimeException 为默认的
对于Service嵌套,无非就是内层service和外层service的注解@Transaction(propagation=)的组合,
有篇文章写的不错:Spring事务传播行为详解,这里也不做够多介绍,主要是为了下文的事务高级篇做铺垫的。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!