我可以相信postgresql中的每个update语句都是原子的吗?
在说postgresql中的每个更新语句都是原子语句之前,我读了一些材料 比如说,我可以相信postgresql中的每个update语句都是原子的吗?,postgresql,concurrency,parallel-processing,database-concurrency,Postgresql,Concurrency,Parallel Processing,Database Concurrency,在说postgresql中的每个更新语句都是原子语句之前,我读了一些材料 比如说, update set column_1 = column_1 + 100 where column_2 = 10; 尽管我有多个进程同时调用更新,但我可以相信它们将按顺序发生,因为每个更新都是幕后的原子,并且“读\修改\写”周期封装在一个包中 但是,如果update语句如下所示,该怎么办 update set column_1 = myFunction(column_1) where column_2 = 10
update set column_1 = column_1 + 100 where column_2 = 10;
尽管我有多个进程同时调用更新,但我可以相信它们将按顺序发生,因为每个更新都是幕后的原子,并且“读\修改\写”周期封装在一个包中
但是,如果update语句如下所示,该怎么办
update set column_1 = myFunction(column_1) where column_2 = 10;
这里,myFunction()是我创建的一个存储过程。在这个函数中,我将根据列_1的数量对其应用不同的数学运算。比如:
if(column_1 < 10):
// do something
else if (column_1 < 20):
// do something
else
// do something
if(列1<10):
//做点什么
否则,如果(列_1<20):
//做点什么
其他的
//做点什么
在这种情况下,当单个update语句包含自定义函数时,它是否保持原子性?好的,@Schwern的Perl知识可能是世界级的,但关于PostgreSQL事务,我可以纠正他:-) PostgreSQL中的每一条语句都是在事务中执行的,可以是您自己开始/提交的显式语句,也可以是封装该语句的隐式语句。在语句期间,您将看到整个数据库的稳定视图 如果将
myFunction
作为pl/pgsql或类似语句中的数据库内自定义函数编写,则它也将与调用它的语句位于同一事务中。如果它不运行自己的查询,只对其参数进行操作,那么您就不需要进一步思考
如果您是从函数中的表中读取数据,那么您需要暂时熟悉。特别是,请确保您理解“readcommitted”对于查看其他流程的活动意味着什么
您提到的博客文章讨论了在数据库之外执行操作。它所提出的解决方案正是您所要求的——原子更新。更新、子查询和函数调用中的查询都应该看到一致的数据视图 从 在内部,通过使用多版本模型(多版本并发控制,MVCC)来维护数据一致性这意味着,无论基础数据的当前状态如何,每个SQL语句都会像一段时间以前一样看到数据的快照(数据库版本)。这防止语句查看在相同数据行上执行更新的并发事务产生的不一致数据,为每个数据库会话提供事务隔离 这意味着,我相信,对于每一个陈述,Postgres都会保留一个版本的数据。每个语句在整个运行过程中都会看到数据库的一致版本。这包括子查询和函数调用
这并不意味着您不必考虑并发性。这只是意味着
update
将看到一致的数据。您可以通过将其放入事务中来避免不确定性。@Schwern但我应该将哪个块事务化?关于更新声明?喜欢开始;更新集合column_1=myFunction(column_1),其中column_2=10;承诺@JaneL需要原子化的部分。这看起来像是更新
,是的。这将包括更新所做的任何事情,例如子查询和函数。@Schwern我以前考虑过这个解决方案,但一篇文章让我担心。在“事务不阻止这种情况吗?”节,它说,甚至开始/犯罪无法阻止读修改写并发竞争。我不知道这是怎么发生的,一句话总是原子的。它总是看到语句开始时数据库的一致快照,包括语句内部使用的任何函数或它可能使用的子查询。我首先承认,我不是Postgres专家。对我的回答有什么反馈吗?