【问题标题】:Postgres: How to prevent read with explicit lock?Postgres:如何防止使用显式锁定读取?
【发布时间】:2017-01-08 04:24:05
【问题描述】:

我有一个类似于聊天轮盘赌的应用程序,其中用户是随机匹配的。我通过将两个用户与 user.looking == true 匹配来在数据库级别执行此操作

但是,如果用户 A 正在等待而用户 B 和 C 同时继续,这很容易受到攻击。

有没有办法锁定一条记录,以便在我进行查询时无法读取它?就像用户 B 首先进行 SELECT * FROM users WHERE looking=true 查询(这将返回用户 A)一样,我希望相同的查询不为用户 C 返回任何内容。

我在看这个:https://www.postgresql.org/docs/9.1/static/explicit-locking.html 但是行级锁看起来不适合读取?

除了表级锁,还有行级锁,可以 是排他锁或共享锁。一个独占的行级锁 更新行时自动获取特定行或 删除。锁一直保持到事务提交或回滚, 就像表级锁一样。行级锁不影响数据 查询;他们只阻止同一行的写入者。

基本上我需要一种方法

1) 查找记录

2) 更新它

没有另一个线程找到相同记录的风险。

【问题讨论】:

  • 只需更新它 - 它会自动锁定。

标签: postgresql


【解决方案1】:
  1. 如果A B C同时做查询,而你只想要一个能得到像user.looking == true这样的记录,就更新记录,这里pg实际上会做三步

    • 开始;
    • 更新记录
    • 提交;

假设 A 进行更新,B 想同时更新记录,B 将阻塞在更新记录步骤。貌似A锁了记录,其实是MVCC阻塞了B的更新。更新锁表用ROW EXCLUSIVE锁,ROW EXCLUSIVE不阻塞ROW EXCLUSIVE锁。

当A B同时更新时:

example here1

example here2

【讨论】:

    猜你喜欢
    • 2021-06-24
    • 2010-11-06
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多