2010-12-21 104 views
2

我將一行插入ORACLE數據庫表中,其中 主鍵ID是自動增量。 和 我正在從該表重試自動增量的ID。在Oracle數據庫中獲取正確的自動增加的ID

在許多人使用相同的表的情況下。 我可能會遇到消費者生產者問題,我可能會在其中獲得其他用戶的ID號碼爲 。

一些用戶對SO提到有關獲取這些遞增ID 是基於connection,不會在消費者生產者造成 問題:

只是想檢查下面的事情與SO:

第一:

我會得到確切的自動遞增ID從下面sceneario:

1) Two computer with in different subnet using DB. 
2) Two computer wiht in same subnet using DB. 
3) Two process using using DB connection. 
4) Two thread uisng DB connection. 

If my insert is: 
Insert into Tables (ID,NAME,DESCRIPTION) values (DBNull,'Name','Description'); 

What should be my query to get the autoincremented ID generated for above 
Insert. 

C# related command will do much help :) 

回答

4

您應該使用返回條款:

declare 
    v_id TABLES.ID%TYPE; 
begin 
    Insert into Tables (ID,NAME,DESCRIPTION) 
    values (seq.nextval,'Name','Description') 
    RETURNING id INTO v_id; 
-- 
    dbms_output.put_line(v_id); 
end; 

這樣你實際上被插入,而不必重新查詢了最高的ID和希望的ID這是正確的。

+0

對不起回覆遲到。我想你正在談論存儲過程。但是我不能在DataBase Side中改變任何東西 – vrbilgi 2011-01-03 10:21:59

2

首先,沒有像「自動增量」ID這樣的生物。 Oracle具有序列和觸發器。可以使用觸發器在插入時選擇序列值。 Oracle不保證順序生成順序,但不保證這些值沒有差距。它確實保證你會得到一個獨特的價值。所以實際上沒有查詢會告訴你最後一個序列被添加到表中。 MAX可能是正確的,但是從序列的緩衝區中拔出一個較低的數字,並在插入之前延遲,然後在較高的數字之後出現。

克雷格有正確的做法的最佳答案。剩下的是討論你的四種情況。

您需要詳細閱讀ACID

ACID(原子性,一致性,隔離 ,耐用性)是一組 性質保證數據庫 事務被可靠地處理。

鑑於您的代碼可能具有併發性問題(即競爭條件或非線程安全),數據庫不存在此類問題。 (不應該,通常也不會)良好的數據庫從頭開始設計以滿足ACID的需求。每筆交易都與每筆交易隔離開來。如果您插入該表並在同一個交易中選擇最大(ID),然後我插入該表並選擇MAX(ID)作爲我的一筆交易的一部分,我將看到插入的號碼,您將看到插入的號碼。任何給定的交易將只顯示交易開始時存在的數據。

您可以通過更改隔離級別來覆蓋此功能,但ACID是一件好事。你要這個。Oracle長期以來一直這樣工作。

在設計不佳的數據庫中,隔離是通過鎖定完成的。如果您閱讀了一行並保持事務處於打開狀態,爲了確保您的下一次閱讀是相同的,您要求的行被鎖定。這意味着讀者可以阻止作家 - 這是一件壞事。在Oracle中,從版本5或版本6開始,Oracle可以通過MultiVersion Concurrency Control重新創建表中數據的視圖,因爲它在交易開始時顯示。這已經是甲骨文20年來的默認行爲。並非每個數據庫都是如此先進......確保在數據庫中執行任何操作之前,瞭解您正在使用的隔離級別。

相關問題