postgresql - 在 Postgresql 中锁定事务(一系列选择和更新)

标签 postgresql locking

我有一个表和几个线程(系统),它们从表中读取特定列并更新它。所以我的查询如下:

Begin;
SELECT col FROM tbl WHERE <condition1>
UPDATE tbl SET col = col + 1 WHERE <condition1>
Commit;

我想确保在任何时候都只有一个线程可以选择和更新该列。什么是最佳解决方案?

PS:据我所知,在 SQL Server 中使用事务会锁定事务中的所有资源,但我对 PostgreSQL 一无所知。

谢谢!

最佳答案

SQL 中最高级的锁是行锁。

无法锁定列,数据库总是在整行(该行的所有列)上加锁。

您可以使用 a SELECT .. FOR UPDATE clause :

Begin;
SELECT col FROM tbl WHERE <condition1> FOR UPDATE;
UPDATE tbl SET col = col + 1 WHERE <condition1> ;
Commit;

SELECT .. FOR UPDATE 的工作方式类似于普通的 select(它从表中检索行),但除此之外,它还会对所有检索到的行进行锁定,以防止它们被其他事务修改,直到当前交易结束。

您还可以使用 RETURNING clause in UPDATE statement :

Begin;
UPDATE tbl SET col = col + 1 WHERE <condition1> 
   RETURNING col - 1 AS col;
Commit;

UPDATE 语句总是在修改后的记录上放置写锁。

RETURNING 子句导致返回值,就像普通的 SELECT 一样,但是它返回修改后的行值(更新后的行值),因此 col - 1 表达式在上面的示例中使用,用于在列值递增之前计算列值。

请看一下这个演示 --> http://www.sqlfiddle.com/#!15/4d0f4/3

第二种方法(UPDATE+RETURNING 子句)的优点是记录只被访问一次,与第一种方法相比,当行必须首先被 SELECT 语句选择时(第一次访问),然后使用 UPDATE 语句(第二次访问)对其进行更新。

关于postgresql - 在 Postgresql 中锁定事务(一系列选择和更新),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21097246/

相关文章:

python - 为什么从 django.contrib.postgres.fields.JSONField 返回的数据是一个字符串?

ruby-on-rails - 找不到 PostgreSQL 客户端库 (libpq)

java - 有没有办法在java(或scala)信号量对象中​​包含条件来获取方法?

php - MySQL 表锁定(读)

python - Django/Mezzanine/S3/Bootstrap - 寻找本地开发/远程生产设置建议

postgresql - Postgres : Add full-text search on existing varchar column?

json - 取消嵌套包含 json 列表的列

c++ - 删除 std::lock_guard 相对于其他堆栈分配对象的顺序/速度?

windows-runtime - Metro App FileIO.WriteTextAsync 多线程

Node.js 一次锁定一个用户