我一直在阅读两期锁定的内容,并了解到这涉及两个阶段:
1. Growing phase: locks are acquired gradually and no locks are released.
2. Shrinking phase: locks are released gradually and no locks are acquired.我的问题是,两相锁定(而不是“严格的两相锁定”)机制如何知道它何时开始收缩阶段?除非DB知道事务中的所有查询(这违背了两阶段锁定机制的全部要点,这种机制应该能够在不知道事务中的所有查询的情况下确保可序列化),否则无法判断事务是否需要获得更多的锁。
假设我有如下事务:
start transaction;
select * from test_tab where id=1;
select * from test_tab where id=2;
update test_tab set age=100 where id=3;
commit;从上面的事务来看,在完成最后一个update语句之前,两阶段锁定机制不应该释放任何锁(因为它需要在这里获得一个锁,并且它不能在收缩阶段获得一个锁)。但是,DB如何知道它是否可以开始收缩阶段,除非客户机到达事务结束并提交(因为DB永远不知道客户机是否会在提交之前发送一个新的更新查询)?我是不是误会了什么?
发布于 2022-05-02 15:17:22
维基百科关于两阶段锁定的文章说:
通常,在第1阶段结束时,事务中没有明确的知识,只有当事务完成处理并请求提交时,才能安全地确定它。在这种情况下,所有锁都可以一次释放(第二阶段)。
所以我认为你对这个理论的理解是正确的。
值得注意的是,既然您标记了这个问题mysql,我不认为MySQL的InnoDB引擎实现了两阶段锁定。
锁是乐观地获得的,因为每个需要锁的SQL语句都被执行。
读锁和写锁通常在事务结束(提交或回滚)之前都不会释放。https://dev.mysql.com/doc/refman/8.0/en/innodb-autocommit-commit-rollback.html说:
提交和回滚都释放在当前事务期间设置的所有InnoDB锁。
以上可能支持两阶段锁定,但也有一些例外情况,即在获得其他锁之前释放锁。例如,在读提交的隔离级别中,不匹配行上的行锁将被释放.事务可能有其他SQL语句,需要在此之后获取锁。因此InnoDB的锁定实现不符合两阶段锁定的定义。
另一个例子是自动增量锁,它是在每个INSERT语句中获取和释放的.
https://dba.stackexchange.com/questions/311552
复制相似问题