MySQL的两阶段所协议2PL

微信搜索『coder-home』,或者扫一扫右侧的二维码,关注『程序猿集锦』。
了解更多干货分享,还有各类视频教程。
扫描它,带走我。

背景

经常听到别人说2PL,猛的一听当时真的是一脸懵逼的感觉,啥意思?2PL是什么玩意?后来又听人说两阶段锁协议,这个又是什么?我咋没有听过呢?

后来才知这是MySQL中的一个术语:2PL(Two-phase locking),翻译成中文就是两阶段锁协议。

废话不多说,我们来用实际的例子体验一把。

准备实验环境

实验的前提条件:

  • RR可重复读事务隔离级别
  • MySQL的版本是5.7.24
  • 使用innodb存储引擎的表来测试

建表语句

实验使用到的表结构如下所示:

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `name` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

初始化数据

此次实验中使用到的初始化数据如下所示:

insert into t(id, name) values(1, 'A');
insert into t(id, name) values(2, 'B');
insert into t(id, name) values(3, 'C');
insert into t(id, name) values(4, 'D');

最终环境

最后准备的环境如下:
在这里插入图片描述

实验

实验步骤

我们来简单说一下实验的具体步骤:

  1. 开启一个左侧的事务。
  2. 开启一个右侧的事务。
  3. 在左侧事务中查询表t中的所有数据。
  4. 在右侧事务中查询表t中的所有数据。
  5. 在左侧事务中,获取id=3的数据行的X锁。
  6. 在左侧事务中,更新id=3的数据行内容。
  7. 在左侧事务中,查询更新后的id=3的数据行内容。
  8. 在左侧事务中,获取id=2的数据行的X锁。
  9. 在右侧事务中,尝试获取id=3的数据行的X锁,获取失败。

实验截图

实验的截图如下所示:
在这里插入图片描述

问题:为什么在第9步中,没有获取到id=3的数据行的X锁呢?按道理左侧的事务已经修改完成了id=3的数据行,它已经去获取了id=2的数据行的X锁了,id=3的竖行的X锁对它已经没有用了,为什么在右侧事务中仍然不能获取到id=3的数据行的X锁呢?

答案:MySQL中的两阶段锁协议的工作机制就是这么设计的。

总结

在MySQL中,两阶段锁协议的含义是:当一个事务获取到了某一个数据库对象的锁之后,并不是当前事务不需要操作它了之后,这个锁就会马上释放掉,这个锁会一直被这个事务持有,直到这个事务被提交或回滚后,这个锁才会被释放掉。所以,在当前事务还没有结束的时候,任何其他事务尝试获取这个锁的时候,都会被阻塞。知道当前事务提交或回滚后,前提事务才可以获取到这把锁。

这就是MySQL中2PL两阶段锁协议的含义。它在事务并发的时候,为数据的一致性提供有力的保障。

微信搜索『coder-home』,或者扫一扫右侧的二维码,关注『程序猿集锦』。
了解更多干货分享,还有各类视频教程。
扫描它,带走我。
### 阶段锁定协议中的死锁及其解决方案 #### 死锁产生的原因 在阶段锁定协议2PL)中,当多个事务竞争同一资源并相互等待对方释放所需资源时就会发生死锁。具体来说,在个或更多事务之间形成循环等待链的情况下会出现这种情况。例如: - 假设存在个事务T1和T2。 - T1已经获得了X对象上的写锁,并请求Y对象上的读/写锁; - 同时,T2已获得Y对象上的写锁,并尝试获取X对象上的读/写锁。 此时就形成了一个循环依赖关系:T1等待T2释放Y的锁;而T2也在等待T1释放X的锁。这种情况下既定时间内双方都无法继续前进,从而构成了死锁状态[^1]。 #### 调度解决方法 为了防止此类情况的发生,数据库管理系统通常采用以下几种策略之一来处理潜在的死锁问题: ##### 主动预防措施 一种常见的主动预防方式是在设计应用程序逻辑之初便考虑好数据访问模式,尽可能减少不同事务间对于相同资源的竞争程度。比如通过合理规划表结构、优化查询语句等方式降低并发冲突的可能性[^4]。 ##### 动态检测机制 另一种更为普遍的方法则是依靠DBMS内置的功能来进行动态监测——即周期性地检查当前正在运行的所有活动事务是否存在可能构成死锁的关系图谱。一旦发现有死锁迹象,则会选择牺牲掉其中一个参与者(通常是回滚最近开始的那个),以此打破僵局并允许其余进程恢复正常运作。 ##### 时间戳排序算法 时间戳排序也是一种有效的手段,它给每一个新发起的事物分配唯一的时间戳值作为优先级标识符。当遇到资源争用时,按照各自所携带的时间戳大小决定谁先取得使用权。这种方法可以在一定程度上避免因随意抢占而导致的恶性循环现象出现[^2]。 ```sql -- 示例SQL用于展示如何设置MySQL InnoDB引擎下的自动死锁检测功能 SET innodb_lock_wait_timeout = 50; -- 设置超时时间为50秒 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值