sql - 锁定 postgres 中的特定行
问题描述
我对 Postgres 还很陌生,我正试图弄清楚如何锁定表格的特定行。
例如,我有一个用户表:
Name: John, Money: 1
Name: Jack, Money: 2
在我的后端,我想选择 John 并确保在我的事务完成之前没有其他调用可以更新(甚至可能选择)John 的行。
我想我需要一个我在网上阅读的内容的排他锁?我似乎找不到一个很好的例子来锁定在线表中的 1 行,知道吗?
编辑 - 我应该在像@SqlUpdate 这样的方法级别(或某种形式 - 使用 org.skife.jdbi.v2)还是在查询本身中这样做?
解决方案
如果要将表锁定在特定的选定行中,则需要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)语句。
我在一个函数中使用它来控制子序列,它很棒。希望你喜欢。
推荐阅读
- sql - SQL查询从多个表中选择并创建第三个表
- c++ - 添加共同祖先后,如何保留 POD 结构的初始化器列表?
- arrays - 从 BIN 文件中扫描(读取)
- javascript - 如何在 PHP 网站上检查 Python 脚本的输出?
- php - 如何卷曲图像类型的投影图像?
- react-native - 是否可以将我的 react-native 应用程序与 MariaDB 连接起来
- python - 定义可微的自定义损失函数TF2.0
- java - 总结 if 语句并从另一个对象中读取 if 条件,如 String[](动态 If)
- github-actions - 在 GitHub Actions 中保存 GITHUB_ENV 变量
- reactjs - 无法更新反应状态,即使组件未卸载