我正在处理在oracle 11.2表中实现的一种消息队列。我知道,这是错的,我仍然拥有它。
表格包含 ID ,消息,日期和状态。插入的所有新邮件的状态为新。我正在开发java(jdbc)阅读器,它选择最新的新消息:
select * from messages
where status = NEW and rownum <= 1
order by date asc
比读者处理消息并将其状态设置为DONE。它工作得很好,而我们有单个读者。多个读者的问题是,他们都选择了相同的信息。
我正在尝试通过将状态更新为WORKING来解决此问题。跟随伪代码是否正确?
//autocommit is on
id = query(select … for update)
query(update messsages set status = WORKING where id = :id)
…do some processing in reader…
query(update messsages set status = DONE where id = :id)
它适用于多个并发读者吗?读者大部分时间都在等锁?或者他们将获得下一个没有锁定的行?
答案 0 :(得分:1)
除非您在skip locked
中添加select for update
条款,否则多位读者都会等待。 From the documentation:
默认情况下,
SELECT FOR UPDATE
语句会一直等到获取请求的行锁定。要更改此行为,请使用NOWAIT
语句的WAIT
,SKIP LOCKED
或SELECT FOR UPDATE
子句。
And:
SKIP LOCKED
是处理锁定某些感兴趣行的竞争事务的另一种方法。指定SKIP LOCKED
以指示数据库尝试锁定WHERE
子句指定的行,并跳过发现已被另一个事务锁定的行。