首页 > 解决方案 > 锁定 postgres 中的特定行

问题描述

我对 Postgres 还很陌生,我正试图弄清楚如何锁定表格的特定行。

例如,我有一个用户表:

Name: John, Money: 1
Name: Jack, Money: 2

在我的后端,我想选择 John 并确保在我的事务完成之前没有其他调用可以更新(甚至可能选择)John 的行。

我想我需要一个我在网上阅读的内容的排他锁?我似乎找不到一个很好的例子来锁定在线表中的 1 行,知道吗?

编辑 - 我应该在像@SqlUpdate 这样的方法级别(或某种形式 - 使用 org.skife.jdbi.v2)还是在查询本身中这样做?

标签: sqlpostgresql

解决方案


如果要将表锁定在特定的选定行中,则需要LOCK FIRST使用该FOR UPDATE / FOR SHARE语句。例如,在您的情况下,如果您需要锁定第一行,请执行以下操作:

BEGIN;

LOCK TABLE person IN ROW EXCLUSIVE MODE;

-- BLOCK 1

SELECT * FROM person WHERE name = 'John' and money = 1 FOR UPDATE;

-- BLOCK 2

UPDATE person set name = 'John 2' WHERE name = 'John' and money = 1;

END;

BLOCK1前面的SELECT语句中,你什么都不做,只是告诉数据库“嘿,我会在这个表上做点什么,所以当我做的时候,在这个模式下锁定这个表”。您可以选择/更新/删除任何行。

但是BLOCK2当您使用时,FOR UPDATE您将该行锁定到其他事务到特定模式(阅读文档以获取更多详细信息)。将被锁定,直到该事务结束。

SELECT ... FOR UPDATE如果您需要一个示例,请在BLOCK2第一笔交易结束之前进行测试并尝试再做一次。它将等待第一个事务结束并在它之后立即选择。

只有 ACCESS EXCLUSIVE 锁会阻塞 SELECT(没有 FOR UPDATE/SHARE)语句。

我在一个函数中使用它来控制子序列,它很棒。希望你喜欢。


推荐阅读