【发布时间】:2019-02-28 20:52:57
【问题描述】:
在说postgresql中的每个更新语句都是原子的之前,我阅读了一些资料。
例如,
update set column_1 = column_1 + 100 where column_2 = 10;
即使我有多个进程同时调用更新,我也可以相信它们会按顺序发生,因为每个更新都是在幕后进行的,并且“read_modify_write”循环被封装在一个包中。
但是,如果更新语句如下所示:
update set column_1 = myFunction(column_1) where column_2 = 10;
这里,myFunction() 是我创建的一个存储过程。在这个函数中,我将根据它的数量对 column_1 应用不同的数学运算。比如:
if(column_1 < 10):
// do something
else if (column_1 < 20):
// do something
else
// do something
在这种情况下,当单个更新语句包含自定义函数时,它是否保持原子性?
【问题讨论】:
-
您可以通过将其放入事务中来避免不确定性。
-
@Schwern 但是我应该交易哪个区块?围绕更新声明?喜欢开始;更新集 column_1 = myFunction(column_1) where column_2 = 10;提交;?
-
@JaneL 需要原子化的部分。这看起来像
update,是的。这将包括update所做的任何事情,例如子查询和函数。 -
@Schwern 我之前想过这个解决方案,但是一篇文章让我担心。 blog.2ndquadrant.com/… 在`事务不阻止这种情况吗? ` 部分,它甚至表示 BEGIN;/COMMIT;不能防止读-修改-写并发竞争。我不确定这是怎么发生的。
-
单个语句始终是原子的。它始终会看到语句开始时数据库的一致快照 - 包括语句内部使用的任何函数或它可能使用的子查询。
标签: postgresql concurrency parallel-processing database-concurrency