整理的八股文
常见的锁类型有以下几种
1.表级锁(Table Lock)
通俗解释:好比把整个餐厅锁起来。一个人要做大扫除时,锁上餐厅门,其他人都进不去。这样不会有任何冲突,但其他人只能等大扫除完成后再进入餐厅。
特点:
开销小,锁得快。
不会有死锁,因为只有一个人能进餐厅。
并发性最低,因为一次只能一个人进
2.行级锁(Row Lock):
通俗解释:好比锁住餐厅里的一张桌子。每个人可以锁住自己那张桌子,做自己的事,互不干扰。虽然可能会有冲突,比如两个人同时想用同一张桌子,但总体上大家可以同时工作。
特点:
开销大,锁得慢。
可能会出现死锁,比如两个人互相等对方释放桌子。
并发性最高,因为很多人可以同时在不同的桌子上工作。
3.页面锁(Page Lock):
通俗解释:好比把餐厅里的一个区域锁起来。一个人锁住一个区域,这个区域里的人不能同时工作,但其他区域的人可以继续工作。
特点:
开销和速度介于表锁和行锁之间。
也可能会出现死锁。
并发性一般。
Read Uncommitted(读未提交):
案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,但还没有提交。
过程
:
- 事务B将余额改为2000元,但还未提交。
- 事务A读取余额,看到的是2000元(未提交的数据)。
- 事务B回滚(因为某种原因)。
- 事务A读到的2000元其实是无效的数据。
问题:脏读,事务A读取到了事务B未提交的数据。
Read Committed(读已提交):
案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,并提交。
过程
:
- 事务A读取余额,看到的是1000元。
- 事务B将余额改为2000元,并提交。
- 事务A再次读取余额,看到的是2000元。
问题:不可重复读,事务A两次读取同一个数据,结果不同。
Repeatable Read(可重复读):
案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,并提交。
过程
:
- 事务A读取余额,看到的是1000元。
- 事务B将余额改为2000元,并提交。
- 事务A再次读取余额,仍然看到的是1000元。
问题:幻读,虽然避免了不可重复读,但在某些情况下,新增的数据可能会造成幻觉。例如,事务B插入了新的符合事务A查询条件的记录。
Serializable(可串行化):
案例:事务A读取账户余额,事务B尝试将账户余额从1000元改为2000元。
过程
:
- 事务A读取余额,看到的是1000元。
- 事务B尝试修改余额,但会被阻塞,直到事务A结束。
- 事务A提交或回滚。
- 事务B修改余额,并提交。
问题:没有并发问题,所有操作都是串行执行的,确保了最高的数据一致性,但性能可能会受到影响,因为事务B必须等待事务A完成。
总结:
- Read Uncommitted:你能看到其他人未完成的工作。
- Read Committed:你只能看到其他人完成的工作,但每次看结果可能不一样。
- Repeatable Read:你每次看到的结果一致,但可能会有新的数据插入影响最终结果。
- Serializable:所有事务按顺序执行,确保完全一致,但性能最低。
通过这个案例,希望你能更清楚地理解这四种事务隔离级别的区别和应用场景。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Taotaozi-Blog!