我有一个典型的生产者 - 消费者问题:
多个生产者应用程序将作业请求写入PostgreSQL数据库上的作业表.
作业请求的状态字段在创建时包含QUEUED.
有多个由当生产者插入一条新记录的规则通知的消费应用:
CREATE OR REPLACE RULE "jobrecord.added" AS
ON INSERT TO jobrecord DO
NOTIFY "jobrecordAdded";
Run Code Online (Sandbox Code Playgroud)
他们将尝试通过将其状态设置为RESERVED来保留新记录.当然,只有消费者才能成功.所有其他消费者不应该保留相同的记录.他们应该保留state = QUEUED的其他记录.
示例:某个生产者将以下记录添加到表jobrecord:
id state owner payload
------------------------
1 QUEUED null <data>
2 QUEUED null <data>
3 QUEUED null <data>
4 QUEUED null <data>
Run Code Online (Sandbox Code Playgroud)
现在,两个消费者A,B想要处理它们.他们同时开始跑步.一个应该保留id 1,另一个应该保留id 2,然后完成的第一个应该保留id 3等等.
在纯多线程世界中,我会使用互斥锁来控制对作业队列的访问,但消费者是可以在不同机器上运行的不同进程.它们只访问同一个数据库,因此所有同步都必须通过数据库进行.
我在PostgreSQL中阅读了很多关于并发访问和锁定的文档,例如http://www.postgresql.org/docs/9.0/interactive/explicit-locking.html 选择Postgresql PostgreSQL中的解锁行并锁定
从这些主题中我了解到,以下SQL语句应该能够满足我的需求:
UPDATE jobrecord
SET owner= :owner, state = :reserved
WHERE id = (
SELECT id from jobrecord …Run Code Online (Sandbox Code Playgroud)