运行UPDATE时PostgreSQL中的死锁

运行UPDATE时PostgreSQL中的死锁,第1张

概述阅读有关PostgreSQL死锁的一点点困惑. 一个典型的僵局的例子是: -- Transaction 1UPDATE customer SET ... WHERE id = 1UPDATE customer SET ... WHERE id = 2-- Transaction 2UPDATE customer SET ... WHERE id = 2UPDATE customer S 阅读有关Postgresql死锁的一点点困惑.

一个典型的僵局的例子是:

-- Transaction 1UPDATE customer SET ... WHERE ID = 1UPDATE customer SET ... WHERE ID = 2-- Transaction 2UPDATE customer SET ... WHERE ID = 2UPDATE customer SET ... WHERE ID = 1

但是如果我更改代码如下:

-- Transaction 1UPDATE customer SET ... WHERE ID IN (1,2)-- Transaction 2UPDATE customer SET ... WHERE ID IN (1,2)

这将是一个僵局的可能吗?

本质上我的问题是:在第二种情况下,Postgresql会一行一个地锁定一行,还是锁定WHERE条件覆盖的整个范围?

提前致谢!

在Postgresql中,这些行将被更新时被锁定 – 实际上,这个实际工作的方式是每个元组(一行的版本)都有一个名为xmin的系统字段来指示哪个事务使该元组当前(通过插入或更新)和一个名为xmax的系统字段来指示哪个事务已过期该元组(通过更新或删除).当您访问数据时,它会检查每个元组,以确定它是否对您的事务可见,通过根据这些值检查您的活动“快照”.

如果您正在执行UPDATE,并且与您的搜索条件匹配的元组具有xmin,这将使您的快照和活动事务的xmax可见,它将阻止等待该事务完成.如果首次更新元组的事务回滚,则您的事务将唤醒并处理该行;如果第一个事务提交,您的事务将唤醒并根据当前事务隔离级别执行 *** 作.

显然,这种情况的发生是以不同顺序排列的.在RAM中没有可以同时获取所有行的行级锁定,但是如果行以相同的顺序更新,则不能进行循环锁定.不幸的是,建议的IN(1,2)语法不能保证.不同的会话可能具有不同的成本因素的活动,背景“分析”任务可能会改变在生成一个计划和另一个计划之间的表的统计信息,或者可能使用seqscan并受到Postgresql优化的影响,这导致新的排序加入一个已经进行中的“循环”来减少磁盘I / O.

如果您以同样的顺序,应用程序代码或使用游标进行一次更新,那么您将只有简单的阻止,而不是死锁.一般而言,关系型数据库容易出现序列化失败,最好通过框架访问它们,该框架将基于sqlSTATE来识别它们,并从一开始就自动重试整个事务.在Postgresql中,序列化失败将始终具有40001或40P01的sqlSTATE.

http://www.postgresql.org/docs/current/interactive/mvcc-intro.html

总结

以上是内存溢出为你收集整理的运行UPDATE时PostgreSQL中的死锁全部内容,希望文章能够帮你解决运行UPDATE时PostgreSQL中的死锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1169754.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存