选择列并隐藏其他选择
问题描述:
我正在处理一种在oracle 11.2表中实现的消息队列。我知道,这是错误的,我仍然拥有它。选择列并隐藏其他选择
表由ID,消息,日期和状态的。所有新消息都插入状态新。我开发java(JDBC)读者,挑选最古老的新邮件:
select * from messages
where status = NEW and rownum <= 1
order by date asc
比读者处理信息,并将它的状态DONE。它运作良好,而我们有单一的读者。多读者的问题是,他们都选择相同的消息。
我试图通过更新状态到工作来解决这个问题。伪代码是否正确?
//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)
它是否适用于多个并发读取器?读者会在大多数时间等待锁吗?或者他们只会得到下一个没有锁定的行?
答
多位读者将等待,除非您包括skip locked
条款i select for update
。 From the documentation:
默认情况下,
SELECT FOR UPDATE
语句会一直等到获取请求的行锁定为止。要更改此行为,请使用SELECT FOR UPDATE
语句的NOWAIT
,WAIT
或SKIP LOCKED
子句。
And:
SKIP LOCKED
是处理被锁定某些感兴趣的行有竞争事务的另一种方式。指定SKIP LOCKED
指示数据库尝试锁定WHERE
子句指定的行,并跳过任何发现已被另一个事务锁定的行。