分布式事务01 事务基本概念
事务的定义
一组SQL组成的执行单元,该单元要保证整体成功整体失败
本地事务
本地事务出现在关系型数据库中,仅支持单库事务,不可跨库
分布式事务
同一个事务,在操作多个数据库的时候需要保持ACID的特性,通常用于微服务场景下的多服务处理
- 情景:订单、积分、物流等等服务共同操作数据库
事务特性
ACID
A 原子(Atomicity)
- 事务是不可分割的工作单位
- 要么都成功,要么都失败
C 一致(Consistemcy)
- 事务前后状态一致
I 隔离(Isolation)
- 事务可以有多个原子形式并发执行,但是互不干扰
D 持久(Durability)
- 事务执行后,持久化到磁盘,不丢失
事务隔离级别
常见四隔离级别
-
未提交(Read Uncommitted)
以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他写事务(但允许其他读事务)。
- 优点:防止更新丢失
- 缺点:不能防止脏读、不可重复读、幻读
- 实现:排他写锁
-
读提交(Read Committed)
Oracle默认的隔离级别
以操作同一行数据为前提,读事务允许其他读事务和写事务,未提交的写事务禁止其他读事务和写事务。-
优点:防止更新丢失、脏读
-
缺点:不能防止不可重复读、幻读
-
实现:
- 瞬间共享读锁
- 排他写锁
-
-
可重复读取(Repeatable Read)
MySQL默认的隔离级别
以操作同一行数据为前提,读事务禁止其他写事务(但允许其他读事务),未提交的写事务禁止其他读事务和写事务。-
优点:防止更新丢失、脏读、不可重复读
-
缺点:不能防止幻读
-
实现
- 排他写锁
- 共享读锁
-
-
序列化(Serializable)
- 优点:防止更新丢失、脏读、不可重复读、幻读
- 缺点:并发性能最弱
- 实现:必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别的问题
-
脏读:读出了未提交的数据
-情景:
1. A转给B 100 B提交
2. C读取B,A网络波动回滚
3. AB因为原子性,C读出脏数据 -
不可重复读:多次查询,返回不同
数据值
。(查询间隔被另外事务修改)- 情景:
- AB抢同一张火车票
- A犹豫了未支付,B下单了
- 现在A去看车票,没有了
- 解决:
select for update
- 情景:
-
幻读:
- 情景:A读取某范围内记录时,B提交事务,A再次读,A读到了第一次未读到的数据
-
区别:
- 脏读VS不可重复读:脏读读到的是前一个事务未提交的,不可读到的是前一个事务已经提交的
- 不可重复读VS幻读:都是读到另一个事务已经提交的数据(脏读是读到未提交);不可重复读是读同
一个数据值(同一条数据
),幻读是针对一批整体的数据(数据的总数或一张表)
值得反思的面经
答案见上文
- 说说你对事务的理解?
- 说说事务的特性?
- 说说并发实物不隔离,会有什么问题?