页面级锁定是否可以导致试图锁定同一页面上2个不同行的2个事务之间的死锁?

问题描述

根据postgres docs section 13.3.2

除表和行锁外,页面级共享/独占锁 用于控制对共享中表页面的读/写访问 缓冲池。这些锁在一行被删除后立即释放 获取或更新。应用程序开发人员通常不需要 与页面级锁有关,但此处提到它们是为了 完整性。

我的理解是,我不必担心我的事务是否足够大,以至于它们可以锁定足够长的行,从而发生以下情况:T1锁定了P1上的R1,但想锁定R2上的R2,但不能这样做因为T2在P2的R3上有一个锁,并且直到它在P1的R4上得到锁才释放它。

T->交易
P->页
R->行

这个假设是正确的还是我应该使我的交易时间足够短以至于这种锁定不太可能发生?

解决方法

页面级锁始终保持很短的时间,无论您的事务花费多长时间。与其他锁不同,它们是在提交之前释放的,在不再需要时会立即释放。

此外,页面锁总是以无法参与死锁的方式获取(除非PostgreSQL有错误)。

详细信息:

使用LockPage中的src/backend/storage/lmgr/lmgr.c函数获取页锁。当前,当挂起列表集成到主索引(ginInsertCleanup中的函数src/backend/access/gin/ginfast.c)时,它们仅在索引清除期间与GIN索引一起使用:元页被锁定以防止该函数并发执行。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...