2

我有一個帶有「ID」列的數據庫。無論何時數據庫有新條目,我都會從數據庫中獲取最後一個ID,然後增加該值,然後在Insert語句中使用它。數據庫隔離模型

編輯:我需要在多個插入語句中使用的ID。我將從主表中獲取此ID並使用此ID將值插入到相關表中。

NextID = Select Max(ID) + 1 From Table 

    INSERT INTO Table1(ID, Col1, Col2...) Values(NextId, Value1, Value2...) 

    INSERT INTO Table2 (ID,col1,col2....) Values (NextID, Value1, Value2...) 

我不知道這是否是一個好辦法,因爲我知道會有併發問題。 當我的應用程序試圖讀取NextID時,應用程序的另一個實例有可能會嘗試讀取相同的值,因此可能會出現併發問題。

有沒有適當的方法來處理這種情況?我的意思是有辦法設置數據庫隔離級別。對於這種情況,這將是一個合適的隔離級別。

此外,如果有人可以建議我用另一種方法來維護和手動增加數據庫中的ID,我也對此表示贊同。

如果這些信息不夠,請讓我知道您需要什麼。

我正在使用VB和MS Sql Server 2008的ASP.Net。我不想使用SQL Server的內置「身份」。

+1

做一個單一的陳述.... –

+0

@MitchWheat你是什麼意思的單一陳述?我也有同樣的問題...好心建議。 – Monodeep

+0

@MitchWheat是的,這是一個選項,但我需要多個插入語句中的ID。我將從主表讀取nextID並使用該ID插入其他相關表中。 – Nitish

回答

3

以獲取下一個ID的唯一方法是實際插入的行,並使用身份。其他一切都會失敗。所以,你必須開始通過插入父表:

begin transaction; 
insert into Table (col1, col2, col3) values (value1, value2, value3); 
set @Id = scope_identity(); 
insert into Table1(ID, col1, col2) values (@Id, ...); 
insert into Table3(ID, col1, col2) values (@Id, ...); 
commit; 

這是原子和併發安全。

我不想使用SQL Server的內置「身份」。

tl; dr。除非你能明確說明理由爲什麼。你可以正確地做到這一點,或者你可以花時間'忘卻遺忘重新發明輪子。

+0

實際上,Identity的問題在於,我的問題中的ID是可編輯的(不是由用戶或其他邏輯),如果我使用Identity,則無法完成此操作。我知道,讓ID被修改並不明智,但我需要這樣的邏輯。 – Nitish

+1

使用不可變的身份作爲主鍵。使用不同的屬性作爲'邏輯ID'。編輯您的可變邏輯ID ad nauseam,但不要觸摸主鍵不可變的身份。 –

+0

我很抱歉,但我有點困惑,哪一個 - 「身份」或「邏輯ID」應該用作我的ID列。請與我聯繫 – Nitish

1

本質上你有一批三個SQL語句 - 一個選擇和兩個插入。數據庫引擎可以在不同的會話中執行另一個語句,從而破壞數據的一致性 - 其他一些會話可以獲得與您獲得的MAX()值相同的值,並將其用於其他插入語句。阻止數據庫引擎執行此操作的唯一方法是使用事務。用BEGIN TRANSACTION ... COMMIT包裝你的批次,你就完成了。

1

你這樣做精細的方式,你會需要的是事務處理..

BEGIN TRANSACTION 

begin try 
    NextID = Select Max(ID) + 1 From Table 

    INSERT INTO Table1(ID, Col1, Col2...) Values(NextId, Value1, Value2...) 

    INSERT INTO Table2 (ID,col1,col2....) Values (NextID, Value1, Value2...) 

    COMMIT TRANSACTION 
end try 

begin catch 

    ROLLBACK TRANSACTION 
    --exception logging goes here 

end catch 
+0

併發訪問會發生什麼情況?我的意思是假設我正在用事務獲取nextID。現在它會鎖定ID列嗎?如果先前的提交ID是5,那麼第一個請求將得到5 + 1 = 6,但在提交此事務之前,假設在下一個毫秒,另一個請求將讀取Max(ID)的值,該值將返回..最後承諾5 + 1 = 6或6 + 1 = 7?我希望我沒有把你搞糊塗:P – Nitish

+0

只有在可序列化的隔離級別事務中才會起作用........ –

+0

這會有任何關聯的性能問題嗎?我的意思是如果有很多請求,隔離是否會減慢系統速度? – Nitish