我可以相信 postgresql 中的每个更新语句都是原子的吗?
Can I rely on it that every single update statement in postgresql is atomic?
之前看了一些资料说postgresql的每条update语句都是原子的
例如,
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() 是由me.In 这个函数创建的存储过程,我将根据它的数量对column_1 应用不同的数学运算。类似于:
if(column_1 < 10):
// do something
else if (column_1 < 20):
// do something
else
// do something
这样的话,当单条update语句包含自定义函数时,是否保持原子性?
好的,@Schwern 对 Perl 的了解可能是世界级的 class 但关于 PostgreSQL 事务,我可以纠正他:-)
PostgreSQL 中的每条语句都在事务中执行,可以是您 BEGIN/COMMIT 自己的显式语句,也可以是包装语句的隐式语句。在一条语句的持续时间内,您将看到整个数据库的稳定视图。
如果您将 myFunction
编写为 pl/pgsql 中的数据库内自定义函数或类似函数,那么它也将与调用它的语句处于同一事务中。如果它不 运行 它自己的查询,只是对其参数进行操作,那么你不需要再考虑了。
如果您正在阅读函数中的表格,那么您需要对 transaction isolation levels 有一定的了解。特别是,请确保您了解 "read committed" 关于查看其他进程活动的含义。
您引用的博客文章讨论了在数据库外执行操作。它提出的解决方案正是您要问的 - 原子更新。
函数调用中的 update
、子查询和查询都应该看到一致的数据视图。
来自 Chapter 13. Concurrency Control.
Internally, data consistency is maintained by using a multiversion model (Multiversion Concurrency Control, MVCC). This means each SQL statement sees a snapshot of data (a database version) as it was some time ago, regardless of the current state of the underlying data. This prevents statements from viewing inconsistent data produced by concurrent transactions performing updates on the same data rows, providing transaction isolation for each database session.
我认为,这意味着 Postgres 会为每个语句保留一个版本的数据。每个语句在其整个 运行 中看到一个一致的数据库版本。这包括子查询和函数调用。
这并不意味着您不必考虑并发性。这只是意味着 update
将看到一致的数据。
之前看了一些资料说postgresql的每条update语句都是原子的
例如,
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() 是由me.In 这个函数创建的存储过程,我将根据它的数量对column_1 应用不同的数学运算。类似于:
if(column_1 < 10):
// do something
else if (column_1 < 20):
// do something
else
// do something
这样的话,当单条update语句包含自定义函数时,是否保持原子性?
好的,@Schwern 对 Perl 的了解可能是世界级的 class 但关于 PostgreSQL 事务,我可以纠正他:-)
PostgreSQL 中的每条语句都在事务中执行,可以是您 BEGIN/COMMIT 自己的显式语句,也可以是包装语句的隐式语句。在一条语句的持续时间内,您将看到整个数据库的稳定视图。
如果您将 myFunction
编写为 pl/pgsql 中的数据库内自定义函数或类似函数,那么它也将与调用它的语句处于同一事务中。如果它不 运行 它自己的查询,只是对其参数进行操作,那么你不需要再考虑了。
如果您正在阅读函数中的表格,那么您需要对 transaction isolation levels 有一定的了解。特别是,请确保您了解 "read committed" 关于查看其他进程活动的含义。
您引用的博客文章讨论了在数据库外执行操作。它提出的解决方案正是您要问的 - 原子更新。
函数调用中的 update
、子查询和查询都应该看到一致的数据视图。
来自 Chapter 13. Concurrency Control.
Internally, data consistency is maintained by using a multiversion model (Multiversion Concurrency Control, MVCC). This means each SQL statement sees a snapshot of data (a database version) as it was some time ago, regardless of the current state of the underlying data. This prevents statements from viewing inconsistent data produced by concurrent transactions performing updates on the same data rows, providing transaction isolation for each database session.
我认为,这意味着 Postgres 会为每个语句保留一个版本的数据。每个语句在其整个 运行 中看到一个一致的数据库版本。这包括子查询和函数调用。
这并不意味着您不必考虑并发性。这只是意味着 update
将看到一致的数据。