我有一個使用Devart和Entity Framework訪問的Oracle數據庫。在數據庫表中並行讀取和更新
有一張名爲IMPORTJOBS
的表格,列STATUS
。
我也有多個進程同時運行。他們分別讀取IMPORTJOBS
中的第一行,其狀態爲'REGISTERED'
,將其置於狀態'EXECUTING'
,如果已完成,則將其置於狀態'EXECUTED'
。
現在,因爲這些進程並行運行,我認爲以下可能發生:
- 過程A讀取其中有狀態
REGISTERED
排10, - 進程B也讀其仍具有狀態
REGISTERED
排10 , - 進程A將第10行更新爲狀態
EXECUTING
。
進程B不應該能夠讀取第10行,因爲進程A已經讀取並且將要更新其狀態。
我應該如何解決這個問題?把事務讀取和更新?還是應該使用一些版本控制方法或其他方法?
謝謝!
編輯:感謝接受的答案我得到它的工作和記錄在這裏:http://ludwigstuyck.wordpress.com/2013/02/28/concurrent-reading-and-writing-in-an-oracle-database。
謝謝,我試圖執行「SELECT * FROM IMPORTJOBS WHERE STATUSCODE ='REGISTERED'AND ROWNUM <= 1 FOR UPDATE SKIP LOCKED」,但它仍然返回來自不同進程的同一行? – 2013-02-28 08:40:58
(1)確保您已關閉自動提交功能:無法在沒有事務的情況下鎖定某一行。 (2)'FOR UPDATE SKIP LOCKED'和'rownum' [不會像你期望的那樣工作](http://stackoverflow.com/questions/5847228/oracle-select-for-update-behaviour) - 這是因爲在WHERE子句之後,SKIP LOCKED被評估**。使用不帶rownum的選擇,獲取一個(或更多根據需要)行並關閉光標,這是使用SKIP LOCKED的最佳方法。 – 2013-02-28 08:49:20
的確,我不得不把選擇和更新放在一個事務中,現在它可以工作。謝謝!!! – 2013-02-28 09:12:07