我可以依靠它,PostgreSQL中的每个更新语句都是原子的吗?

时间:2019-02-28 20:52:58

标签: postgresql concurrency parallel-processing database-concurrency

我读了一些材料,然后说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

在这种情况下,当单个update语句包含自定义函数时,它是否仍是原子的?

2 个答案:

答案 0 :(得分:1)

好的,@ Schwern对Perl的了解可能是世界一流的,但是关于PostgreSQL事务,我可以纠正他:-)

PostgreSQL中的每条语句都在一个事务中执行,您可以自己开始/提交一个显式语句,也可以包含一个隐式语句。在声明的整个过程中,您将看到整个数据库的稳定视图。

如果您将myFunction作为pl / pgsql中的数据库内自定义函数或类似的东西编写,那么它也将与调用它的语句处于同一事务中。如果它不运行自己的查询,只对它的参数进行运算,那么您就无需再考虑了。

如果您正在从函数中的表中进行读取,则需要对transaction isolation levels有所了解。特别是,请确保您了解“读取已提交”对于查看其他进程的活动意味着什么。

您所引用的博客文章正在讨论在数据库外部执行操作。它提出的解决方案正是您所要的-原子更新。

答案 1 :(得分:0)

函数调用中的update,子查询和查询都应该看到一致的数据视图。

来自Chapter 13. Concurrency Control

  

在内部,通过使用多版本模型(Multiversion Concurrency Control,MVCC)来维护数据一致性。 这意味着每个SQL语句都可以像以前一样看到数据快照(数据库版本),而与基础数据的当前状态无关。 查看并发事务在同一数据行上执行更新所产生的不一致数据,从而为每个数据库会话提供事务隔离。

我认为这意味着Postgres保留每个数据版本的每个语句。每个语句在整个运行过程中都会看到数据库的一致版本。其中包括子查询和函数调用。

这并不意味着您不必考虑并发性。这只是意味着update将看到一致的数据。