2012-03-28 61 views
2

我有以下存儲過程。這是爲了獲得一個名字。如果名稱存在於表格中,則返回其相應的ID。如果它還不存在,它會創建一個新的ID,並用新的ID將它添加到表中。如何同步交易

問題是,當我在多個使用相同名稱的線程(尚未在表中)上運行此操作時,我有時會使用後續ID獲取多次輸入的名稱。

我想要的是在另一個事務正在運行時阻止事務,以便名稱只在數據庫中獲得一次。

是否有隔離級別或選擇提示我應該使用?有沒有另一種方法來做到這一點?

CREATE PROCEDURE [dbo].[sp_createID] 
@name varchar(max) 
AS 
BEGIN 
SET NOCOUNT ON; 
BEGIN TRAN 
    DECLARE @id as int 
    SELECT @id=Id FROM MyTbl WHERE [email protected] 
    IF @id IS NULL 
    BEGIN 
     UPDATE idGeneratorTbl SET lastkey=lastkey+1 
     SELECT @id=lastKey FROM idGeneratorTbl 
     INSERT INTO MyTbl VALUES(@id, @name) 
    END 
    SELECT @id 
COMMIT   
END 

回答

1

這兩個特效應該在同一個事務上來實現你想要的。

您可以通過刪除[sp_generateNewId] proc中的事務控制來實現此目的。

僅供參考,您不必擔心密鑰的生成,你爲什麼不只是創建一個標識字段

+0

我感動sp_generateNewId代碼到sp_createID代碼,刪除多餘的事務控制。不幸的是,這並沒有幫助。 我知道IDENTITY字段。我們在新表中使用它,但這些都是我們產品多年使用的舊錶格,在這一點上我不想改變它們。 – 2012-03-28 10:39:17

+0

多數民衆贊成在奇怪的,我認爲事務正在釋放MyTbl表讀取後,而不是事務提交後的鎖。嘗試使用TABLOCKX或XLOCK做「SELECT @ id = Id FROM MyTbl WHERE name = @ name」請參閱http://msdn.microsoft.com/en-us/library/ms187373.aspx – Diego 2012-03-28 10:56:17

+0

上的說明@Shahar這些是嵌套的交易。內部提交根本沒有提交,所以所有的鎖都保持到外部提交。 – 2012-03-28 11:00:04