数据库4种隔离级别与3级封锁协议

本文主要探讨数据库并发会引发的问题,如脏读、不可重复读、幻读、丢失更新等。同时介绍了不同的隔离级别,包括读未提交、读已提交、可重复读和可串行化,分析了各隔离级别能解决的问题及存在的不足,还提及了相应的封锁协议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库并发会引发的问题
  • 脏读(dirty read):A事务读取B事务尚未提交的更改数据,并在这个数据基础上操作。如果B事务回滚,那么A事务读到的数据根本不是合法的,称为脏读。在oracle中,由于有version控制,不会出现脏读
  • 不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样
  • 幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据
  • 第一类丢失更新:A事务撤销时,把已提交的B事务的数据覆盖掉
  • 第二类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉

1037646-20190711103929028-517565526.png

读未提交

最低隔离级别,允许一个事务能够读到另一个事务未提交的信息,只对修改数据的并发操作做限制(对于数据而言,写之前加X锁,直到事务结束释放X锁,对应一级封锁协议),这样解决了第一类丢失更新的问题,虽然一个事务不能修改其他事务正在修改的数据,但是可以读到其他事务还未提交的修改,如果这些修改未提交,那么就会成为脏数据,所以还未解决脏读的问题,自然,就算是已经提交的数据,多次读取结果也不一定一样,所以还未解决不可重复读幻读的问题(存在的问题:脏读,不可重复读,幻读

读已提交

只能读取已经提交的数据,换句话说,就是一个事务读取其他事务中正在修改的数据是不被允许的(一级封锁协议+读之前加S锁,读完数据释放S锁,对应二级封锁协议),由于读完之后就释放S锁,所以不能保证不可重复读幻读

可重复读

读已提交下,同一事务内,允许多次相同的查询能够得到不同的结果,可以使用二级封锁协议+MVCC使得当前事务只能读取不高于其事务版本的数据,也可以使用三级封锁协议(一级封锁协议+读之前加S锁,直到事务结束释放S锁)能解决可重复读,同时也解决了幻读

可串行化

可重复读与幻读的区别是:可重复读是更改表中行级数据,而幻读是增加表中行级数据,幻读可以通过三级封锁协议消除,可串行化使得所有的事务必须串行化执行,解决了一切并发问题,但会造成大量的等待、阻塞甚至死锁,使系统性能降低

参考

MySQL隔离级别和封锁协议

转载于:https://www.cnblogs.com/qbits/p/11168532.html

### 三封锁协议的概念 三封锁协议是一种用于解决数据库事务中的并发控制问题的方法,其核心在于通过加锁的方式防止多种类型的异常情况发生。具体来说: - **一封锁协议**要求事务在修改数据前必须获得排他锁(X锁),并在此事务完成提交后再释放该锁。这一措施能够有效防止丢失修改的发生[^3]。 - **二封锁协议**是在一封锁协议的基础上增加了新的约束条件:即事务在读取数据之前也需要加上共享锁(S锁)。这种改进不仅解决了丢失修改的问题,还进一步阻止了脏读的情况出现。 - **三封锁协议**则是更严格的一层规定,在前面两基础上再做提升——它强调即使只是打算读取某条记录也需事先申请得到相应别的锁定直至整个过程结束为止才能解锁;如此一来除了上述两种情形之外还能避免不可重复读现象以及幻影读问题的产生。 ### 实现方式 为了达成这些目标,通常会采用如下策略来进行实际操作上的部署: 1. 当某个事务想要更改特定元组时, 它应该首先对该元组施加 X 锁. 2. 如果另一个事务希望读取同一份资料,则前者尚未提交的情况下后者会被阻塞等待,直到第一个事务成功提交或者回滚之后才会解除限制允许第二个事务继续运行下去。 3. 对于那些仅计划检索而不涉及变更的行为而言 (比如 SELECT 查询),同样有必要提前获取 S 锁以保护所访问的信息单元不被中途篡改影响最终结果准确性。 这样的设计思路确保了不同层次间良好的兼容性的同时也为更高标准下的安全性提供了保障基础[^4]。 ```sql -- 设置隔离级别为 SERIALIZABLE 来模拟最严格的封锁效果 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRAN; SELECT * FROM table_name WHERE condition; -- 此处自动应用必要的锁 COMMIT; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值