2014-09-11 173 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子句指定的行,並跳過任何發現已被另一個事務鎖定的行。