加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在Postgresql中选择未锁定的行

发布时间:2020-12-13 16:30:28 所属栏目:百科 来源:网络整理
导读:有没有办法在Postgresql中选择未锁定的行?我有一个多线程应用程序,它将: Select... order by id desc limit 1 for update 在桌子上. 如果多个线程运行此查询,它们都会尝试拉回同一行. 一个获取行锁,另一个获取然后在第一个更新行后失败.我真正喜欢的是第二
有没有办法在Postgresql中选择未锁定的行?我有一个多线程应用程序,它将:
Select... order by id desc limit 1 for update

在桌子上.

如果多个线程运行此查询,它们都会尝试拉回同一行.

一个获取行锁,另一个获取然后在第一个更新行后失败.我真正喜欢的是第二个线程获取与WHERE子句匹配且尚未锁定的第一行.

为了澄清,我希望每个线程在执行select之后立即更新第一个可用行.

因此,如果存在ID为1,2,3,4的行,则第一个线程将进入,选择ID = 4的行并立即更新它.

如果在该事务期间第二个线程出现,我希望它获得ID = 3的行并立即更新该行.

因为WHERE子句将匹配锁定的行(在我的示例中ID = 4),因此Share不会实现此目的,也不会使用nowait.基本上我想要的是WHERE子句中的“AND NOT LOCKED”.

Users

-----------------------------------------
ID        | Name       |      flags
-----------------------------------------
1         |  bob       |        0
2         |  fred      |        1
3         |  tom       |        0
4         |  ed        |        0

如果查询是“从ID为desc limit 1的flags = 0 order in users的用户中选择ID”,当返回一行时,接下来的事情是“Update Users set flags = 1 where ID = 0”那么我想要第一个线程用以获取ID为4的行和下一个用于获取ID为3的行.

如果我将“For Update”附加到select,那么第一个线程获取行,第二个线程阻塞然后不返回任何内容,因为一旦第一个事务提交WHERE子句就不再满足了.

如果我不使用“For Update”,那么我需要在后续更新中添加WHERE子句(WHERE flags = 0),因此只有一个线程可以更新该行.

第二个线程将选择与第一个相同的行,但第二个线程的更新将失败.

无论哪种方式,第二个线程都无法获取行并进行更新,因为我无法让数据库将第4行提供给第一个线程,将第3个第3行提供给事务重叠的第二个线程.

这个功能,SELECT … SKIP LOCKED正在Postgres 9.5中实现. http://www.depesz.com/2014/10/10/waiting-for-9-5-implement-skip-locked-for-row-level-locks/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读