Zso*_*nos 1 postgresql locking
我有点想知道我正在做一张大桌子的更新,我是否需要担心锁。
我有一张桌子,看起来像这样:
CREATE TABLE "ItemsToProcess"(
"id" text,
"WorkerInstanceId" text,
"ProcessingStartTime" timestamp with time zone,
"UpdatedTime" timestamp with time zone,
CONSTRAINT "ITP_PK" PRIMARY KEY ("id")
)WITH (
OIDS=FALSE
);
Run Code Online (Sandbox Code Playgroud)
最初,此表中有〜200万行,并且默认情况下以及运行开始时,仅填充的ID,WorkerInstanceId和两个时间戳为null。
发生的情况是,某些工作人员应用程序(至少两个,但在生产中大约为10-13)会从该表中标记一批ID-s(我计划将batchSize设置为200)进行处理。处理过程中发生的事情现在并不重要。批处理的标记如下所示:
UPDATE "ItemsToProcess"
SET "WorkerInstanceId" = ?, "ProcessingStartTime" = current_timestamp()
WHERE "WorkerInstanceId" is NULL
LIMIT 200;
Run Code Online (Sandbox Code Playgroud)
我的问题是,在进行更新之前,我是否需要担心锁定要更新的行?
Postgres文档说:
排他性
与SHARE,SHARE ROW EXCLUSIVE,EXCLUSIVE和ACCESS EXCLUSIVE锁定模式冲突。
命令UPDATE,DELETE和INSERT在目标表上获得此锁定模式(除了对任何其他引用表的ACCESS SHARE锁定之外)。通常,任何修改表中数据的命令都将获取此锁定模式。
因此,我认为每当一个工作人员进行此更新时,整个表将被锁定,将更新200行,最后释放该锁。在锁到位之前,其他工人正在等待锁释放。我是对的还是我想念什么
谢谢您的帮助!
UPDATE
锁定行,因此您不需要先锁定它。如果尝试同时UPDATE
重叠行集,则第二个UPDATE
将等待第一个的事务提交或回滚。
您的方法最大的问题-除了UPDATE
没有LIMIT
子句的事实之外-多个工作人员都将尝试抓住同一行。这是发生了什么:
worker1:过滤表以查找200行并将其锁定worker1:开始更新行worker2:过滤表以查找200行row2:尝试开始更新行,但是选择了与worker1相同的行,因此它阻塞了worker1的锁worker1:完成更新worker2行:释放锁定后,重新检查WHERE条件,发现没有行匹配,因为worker1已更新它们。更新零行。...然后重复!
您需要:
至于LIMIT
-您可以使用WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id)
-但两个工人选择相同的行集进行更新会遇到相同的问题。
归档时间: |
|
查看次数: |
3295 次 |
最近记录: |