我想知道我正在对一个大表进行的更新,以及我是否需要担心锁。
我有一张像这样的桌子:
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
);
最初,此表有~200万行,并且只有id
列填充-WorkerInstanceId
,默认情况下和运行开始时两个时间戳为NULL
。
发生的情况是,一些辅助角色应用(至少两个,但在生产环境中大约为 10-13 个)将从此表中标记一批 ID(我计划将 batchSize 设置为 200),以便它们进行处理。处理过程中发生的事情现在并不重要。
批次的标记如下所示:
UPDATE "ItemsToProcess"
SET "WorkerInstanceId" = ?, "ProcessingStartTime" = current_timestamp()
WHERE "WorkerInstanceId" is NULL
LIMIT 200;
我的问题是,在进行更新之前,是否需要担心锁定要更新的行?
Postgres文档 说:
排他
与“共享”、“共享”行“独占”、“独占”和“访问独占”锁定模式冲突。
命令UPDATE、DELETE和INSERT在目标表上获取此锁定模式(除了访问任何其他引用表上的共享锁之外)。通常,此锁定模式将由修改表中数据的任何命令获取。
因此,我认为,每当一个工人进行此更新时,整个表都会被锁定,200行被更新,最后锁被释放。在锁到位之前,其他工人正在等待锁释放。这是对的还是我遗漏了什么?
你错过了一些东西。
首先,PostgreSQL不提供用于更新的LIMIT
选项。请参阅UPDATE文档。
其次,注意< code>ROW EXCLUSIVE本身并不冲突,它与不同的< code>SHARE ROW EXCLUSIVE冲突。因此,您的< code>UPDATE语句可以安全地从多个工作线程并发运行。你仍然希望你的更新次数少。但是,如果遇到问题,您已经有了一个内置的方法来调整它,即降低< code>batchSize。
UPDATE
锁定行,因此不需要先锁定它。如果尝试同时<code>更新
您的方法的一个大问题是,除了<code>UPDATE
...重复!
您需要:
至于 LIMIT
- 您可以使用 WHERE id in (SELECT t.id FROM thetable t LIMIT 200 ORDER BY ID)
- 但是两个 worker 选择同一组行进行更新时,您会遇到同样的问题。
我希望在一条语句中更新PostgreSQL中的多行。有没有一种方法可以做到以下几点?
问题内容: 我试图了解如何用不同的值更新多行,但我不明白。解决方案无处不在,但对我来说似乎很难理解。 例如,将三个更新更新为1个查询: 我读了一个例子,但我真的不明白如何进行查询。即: 如果在WHERE和IF条件中存在多个条件,我还不太清楚如何执行查询。 问题答案: 您可以这样操作: 我不了解您的日期格式。日期应使用本机日期和时间类型存储在数据库中。
问题内容: 假设我有一个名为example的表格,如下所示: [abc] | [def] --1 — | -qwerty- --2 — | -asdf — 我想要做的是在一个SQL查询中更新两个列(仅使用一个UPDATE)。 以上是我要实现的内容,但是在一行sql中(使用MySQL)。我知道您可以这样做,但是我不确定如何使用两个不同的where语句来做到这一点。 问题答案: 您可以使用( mysq
我在同一个表上有两个唯一的约束,我想在那个表上做一个upsert语句。 是否可以指定这两个冲突中的上位插入?我看到了这个:如何在Postgres上的冲突上的2列之一上的上位插入? 但是我的问题涉及得更多一些,因为其中一个唯一约束是另一个唯一约束的子集。 unique_constraint_1=(col_1)unqiue_constraint_2=(col_1、col_2) 谢谢!
问题内容: 我运行foo.com。我在foo.com中有两个不同的应用程序:一个是foo.com/bar,另一个是foo.com/example。我使用会话来跟踪有关用户登录的信息,但是如果用户从foo.com/bar转到foo.com/example,则foo.com/example会看到用户从foo.com/启动的会话并使用该信息。我的问题是,如何同时为每个目录进行两个不同的会话? 问题答案:
我想在一条语句中更新PostgreSQL和Go中的多行。有没有办法做如下事情? 还有有没有一个例子,如果用go语言执行?