2013-10-13 32 views
0

我有Windows服務器上某些用戶的數據庫記錄。其中一列是用戶的SID(該用戶的唯一字符串)。使用實體框架在SQL Server表中強制唯一的varchar(255)列值

當我得到一個用戶的消息時,我想首先執行查詢SID列的SID值的記錄。如果沒有記錄被返回,則創建一個具有該SID值的記錄。但是,在查詢和添加之間,另一個線程可以獲得具有相同用戶/ SID的消息。所以我最終可以添加兩次。

  1. 有沒有辦法創建一個事務,在事務完成之前沒有其他記錄可以添加到表中?

  2. 還是有更好的方法來鎖定整個表,因爲無論查詢/添加有多快,這是一個瓶頸點。 (如果這是最好的方式,我可以查詢沒有交易,如果存在則返回,只有在極少情況下不存在,則交易,再次查詢,添加。)

  3. 有沒有辦法告訴SQL Server的列是唯一的?在SQL Server Management Studio中禁用的設置屬性,我假設它是varchar

謝謝 - 戴夫

+0

只要執行'ALTER TABLE dbo.YourTable ADD CONSTRAINT UQ_YourTable_YourColumnName UNIQUE(YourColumnName)',你就完成了SQL Server –

回答

0

你可以在列執行關於列中的值的uniquenss創建唯一索引和您可以使用下面的代碼它調整到你的數據庫的規格, 戰國由於我已將事務隔離級別設置爲SERIALIZABLE,因此如果multipule用戶嘗試添加數據,它會減慢查詢速度,因爲當此事務隔離級別設置爲SERIALIZABLE時,它不允許其他用戶更改或向表中添加數據。 。

CREATE Procedure usp_InsertSID 
@SID varchar(225) 

AS 
BEGIN 
    SET NOCOUNT ON; 
    BEGIN TRY 

      IF @SID IS NULL 
      RAISERROR('Validation Failed: SID is cannot be null', 16,1) 

      IF EXISTS (SELECT SID from tableName 
         WHERE SID= @SID) 
       RAISERROR('Validation Failed: SID already Exists',16,1) 
     SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 
     BEGIN TRANSACTION 

      INSERT INTO tableName(ColumnNames) 
      VALUES (@SID) 

      COMMIT TRANSACTION 
     SELECT @ReturnMessage = 'Sucess! New SID is added.' 
    END TRY 

    BEGIN CATCH 
     IF (@@TRANCOUNT > 0) 
     ROLLBACK TRAN 

     SELECT @ReturnMessage = ERROR_MESSAGE() 

      SELECT @ReturnCode AS ReturnCode, @ReturnMessage AS ReturnMessage, 
       ERROR_LINE() AS ErrorLine, 
       ERROR_SEVERITY() AS ErrorSeverity, 
       ERROR_STATE() AS ErrorState 
    END CATCH 
END 

GO 
+0

我不認爲這是安全的。如果兩個線程並行執行會怎麼樣?兩者都沒有找到SID,然後開始交易。一個運行添加新的SID,提交,然後另一個在開始暫停的運行現在運行。我錯過了什麼嗎? –

相關問題