2014-09-11 175 views
1

我正在处理一种在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) 

它是否适用于多个并发读取器?读者会在大多数时间等待锁吗?或者他们只会得到下一个没有锁定的行?

回答

1

多位读者将等待,除非您包括skip locked条款i select for updateFrom the documentation

默认情况下,SELECT FOR UPDATE语句会一直等到获取请求的行锁定为止。要更改此行为,请使用SELECT FOR UPDATE语句的NOWAIT,WAITSKIP LOCKED子句。

And

SKIP LOCKED是处理被锁定某些感兴趣的行有竞争事务的另一种方式。指定SKIP LOCKED指示数据库尝试锁定WHERE子句指定的行,并跳过任何发现已被另一个事务锁定的行。