我正在处理一种在 oracle 11.2 表中实现的消息队列。我知道,这是错误的,但我仍然拥有它。
表格由id、message、date和status组成。插入所有新消息,状态为 NEW。我正在开发 java (jdbc) 阅读器,它会挑选最旧的新消息:
select * from messages
where status = NEW and rownum <= 1
order by date asc
然后阅读器处理消息并将其状态设置为完成。它运作良好,而我们只有一个读者。多个阅读器的问题在于,他们都选择相同的消息。
我试图通过将状态更新为 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)
它适用于多个并发读者吗?读者大部分时间会在锁上等待吗?或者他们只会得到下一个未锁定的行?
最佳答案
除非您在您的select for update
中包含skip locked
子句,否则多个读者将等待。 From the documentation :
By default, the
SELECT FOR UPDATE
statement waits until the requested row lock is acquired. To change this behavior, use theNOWAIT
,WAIT
, orSKIP LOCKED
clause of theSELECT FOR UPDATE
statement.
And :
SKIP LOCKED
is an alternative way to handle a contending transaction that is locking some rows of interest. SpecifySKIP LOCKED
to instruct the database to attempt to lock the rows specified by theWHERE
clause and to skip any rows that are found to be already locked by another transaction.
关于java - 选择列并从其他选择中隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25785687/