2014-01-11 42 views
2

在我的程序數據模型中,存在一個包含兩列的表,如下所示: Id_1Id_2Number數據類型。此表沒有任何主鍵和唯一鍵。同步從jdbc調用的oracle包

我有一個程序包作爲persist。此過程用於向表中添加一行。 我在包裝過程是如下:

procedure persist(id_1    out Number, 
        id_2    out Number)is 
begin 
    insert into middle_table values(id_1,id_2); 
end; 

問題是:我有一種情況如下: 線程一和線程2的併發呼叫上面相同的參數和結果的程序是:2等於行加入到上面表這在我的應用程序中是錯誤的。

我的問題是:我做什麼來防止這種情況在程序中?

回答

0

你應該總是有一個約束,但是這個要求在某些情況下可能是有效的。

一個簡單而優雅的解決方案是做一個MERGE或做一個SELECTINSERT。所以,執行多少次,你是安全的。

通過將過程調用放入線程類的syncronized方法中,可以實現客戶端實現。所以,它不能並行運行。

public void your_method() { 
    // Other statements 

    synchronized(this) { // blocks "this" from being executed by parallel threads 
     // call your oracle stored proc here 
    } 

} 

但是,如果跨不同平臺有多個客戶端,則可能必須在Oracle本身編寫一些東西! 一個簡單而優雅的解決方案是做一個MERGE或做SELECTINSERT

procedure persist(id_1    out Number, 
        id_2    out Number) 
is 
    retcode NUMBER := 0; 
begin 
    retcode := 100; 
    /* Checking for semaphore, else wait ! */ 
    WHILE(retcode = 100) 
    LOOP 
     retcode = check_semphore(); /* Returns 100 if present else 0 */ 
     IF(retcode = 100) THEN 
      /* Semaphore present */ 
      NULL; 
     ELSE 
      write_semaphore; 
      /* probably a entry in a table with commit, 
      have to use savepoints, else every other transactions would be comitted! */ 

      MERGE INTO middle_table m 
      USING (SELECT id_1,id_2 FROM dual) new_Values 
      ON (new_Values.id_1 = m.id_1 
       AND new_Values.id_2 = m.id_2) 
      WHEN NOT MATCHED 
      THEN 
       INSERT INTO middle_table VALUES(id_1,id_2); 

      delete_semaphore; 
      /* delete tht entry */ 

      EXIT; 

     END IF; 
    END LOOP; 
end; 
/
0

如何在有問題的表中添加唯一約束?

或者不是讓線程直接寫入數據庫,而是將新對象放入散列表中,檢查是否有重複,加入線程,然後使用JPA來存放哈希表中找到的對象。