2011-02-15 96 views
0

我有一個表A(SQL Server 2008),其中包含最小和最大數字的集合。在我的其中一個存儲過程中,我使用此表連接產品表B,以查找介於最小值和最大值之間的可用產品編號,然後插入帶有此產品編號的新產品。所以我想要在最小/最大值之間的下一個免費號碼。我應該如何鎖定以避免重複數字

在找出下一個可用數字並插入產品行之間,我想鎖定以防止任何人找到相同的數字(並給出一個副本)。

我該如何看待這種情況?我是否應該在A表上獲得更新鎖定,即使我從不修改它?在我插入表B並且交易完成後,鎖應該被釋放?此更新鎖是否會阻止其他事務讀取表A?

編輯:最小/最大表格是不同產品系列的表格。根據你想要的系列,我想嘗試一下,找到這個序列中的可用編號。 productnr並不是獨一無二的,但它可以與第二列結合使用。簡化sp:

CREATE PROCEDURE [dbo].[InsertProduct] 
(
@Param1 int, 
@Param2 bit, 
... 
@Param20 int) AS 
BEGIN 
    DECLARE @ProductNr int 
    --Here I do a query to determine which ProductNr I should have. Checking that the number is between max/min in the series and that no other product has this productnr. 
    --Now insert the row 
    INSERT INTO Products VALUES (@Param1, @ProductNr, ...., @Param2 
END 

回答

1

您的問題有點模糊,如果您包含一些示例數據,這將有所幫助。

無論如何,我過去使用的策略是試着用一個語句來包裝所有東西 - 在這裏,它將是一個INSERT。每個SQL語句事實上都被包裝在它自己的隱式事務中(這就是原子性,關係數據庫屬性名稱的ACID中的「A」代表什麼)。在僞代碼,它會看起來像:

INSERT MyTable (Id, Plus, Other, Columns) 
select CalcForNewId, Plus, Other, Columns 
from [what may be a pertty convoluted query to determine the "next" valid Id] 

這隻能如果你可以寫你的業務邏輯作爲一個合理的查詢(這裏的「合理」意味着它不鎖定,禁止或死鎖當前或任何其他用戶的時間長度不合理)。這可能是一個非常高的順序,但我會考慮寫任何與TRY ... CATCH塊混合的複雜BEGIN TRANSACTION/COMMIT/ROLLBACK代碼。 (這當然會起作用,因此我相應地批准了@Scott Bruns。)

1

只需在表B中插入下一個數字。如果它提交它是您的使用。如果您獲得密鑰違規,則意味着不同的進程剛剛輸入了新號碼。在這種情況下,增加新號碼並重試。

數據庫會自動處理您的隱蔽性。不需要手動鎖定。

+0

列上沒有標識。在某些情況下可能會有重複。 – KTrum 2011-02-15 20:08:31

+0

「產品」表中有多個產品具有相同的產品編號? – 2011-02-15 20:18:21