2011-09-12 51 views
0

鎖定這就是我的要求 - 鎖定數據庫記錄,處理它,然後鬆開鎖,工藝和釋放JDBC

環境 - 的WebLogic 10.3 數據庫 - 的Oracle 11g 數據源 - 多XA的recources參與 的Tx經理 - JTA

下面是到目前爲止,我已經做了實驗結果:

實驗1 - 依靠讀取未提交

  1. 讀取數據庫記錄
  2. 通過ID鎖定記錄在另一表中,作爲全局JTA事務
  3. 過程記錄 它試圖鎖定同一記錄將失敗的第二個交易的一部分,將下降記錄。 但是爲了這個工作,RDBMS應該允許髒讀。 不幸的是,Oracle不支持讀取未提交的隔離級別。

實驗2 - 鎖定記錄在本地事務

  1. 閱讀分貝記錄
  2. 另一個表通過ID鎖定記錄,作爲一個獨立的本地事務
  3. 過程中的記錄和在事務成功提交時刪除記錄 嘗試鎖定相同記錄的第二個事務將失敗,將刪除該記錄。這種方法基於承諾的數據,應該工作正常。 這裏是問題 - 由於鎖定事務和全局父項是不同的,如果處理失敗回滾主要事務,我應該回滾鎖定事務,我不知道該怎麼辦 - 需要幫助在這裏

如果Iam無法回滾記錄鎖定事務,將不得不圍繞記錄鎖定代碼編寫一些髒邏輯。我不喜歡這個。

這似乎是一個非常普遍的要求。我想知道你們如何優雅地處理這件事。 Oracle是否支持以任何方式使未提交的更新對所有事務可見。

非常感謝。

+0

在實驗中發生的事情是以下幾點:獲得數據庫記錄,鎖定由ID記錄在另一張表(我假設你插入ID到另一個表,該ID是主鍵)。這將鎖定這條記錄。任何其他試圖將相同密鑰插入表的事務都會阻塞/失敗。 – steve

回答

1

我們有一個實現大致是你在實驗2描述了一個實用工具類:

先決條件:具有用於鎖定

在鎖定期專用表,創建一個新的連接;在鎖定表上執行INSERT INTO。

在解鎖階段,無論執行何種業務邏輯,都會執行連接回滾。

它被用作一個java.util.concurrent.locks。鎖:

Lock lock = new Lock(...); 
lock.lock(); 
try { 

    // your business logic 
} finally { 
    lock.unlock(); 
} 

它適用於websphere/oracle。

請注意,如果你使用JPA,有一個內置的實體鎖定支持。

+0

這是一個完美的工作示例。這裏你的代碼控制整個工作流程。但在我們的情況下,這是春季整合框架。消費者的多個實例駐留在不同的weblogic節點中(每個節點1個)。在處理消息之前,我可以將更改提交到臨時表。我也可以釋放鎖定後處理。但是,如果在消息處理中有一個異常,那麼鎖將會卡住(我在異常情況下沒有回調)。所以我應該在消息處理之前根據鎖的年齡編寫一些髒邏輯。這是我的問題 – Krish

+0

是否有可能管理客戶端的鎖?如果消費者是MDB,攔截器可以管理鎖;它會保持您的業務邏輯清潔。 –

+0

我的目標是保持消息不被傳遞給1個以上的消費者。如果消費者處理中止作爲例外情況是我唯一的出路,這是不優雅的。 – Krish