2011-12-26 71 views
0

我有一個表格,每當用戶點擊我網站上的一個選項時,新的數據被填充。我通過Management Studio創建了這張表,我想澄清一下,我不是每次都通過存儲過程創建此表,也不是使用任何類型的內存中臨時表。修改一個表來處理SPID

無論何時用戶點擊我網站上的選項,該表格中的舊記錄將首先被刪除,並且新記錄被填充。我擔心許多用戶從我的網站點擊相同的選項時可能會出現的併發問題。我不知道SQL Server如何處理多個刪除並插入到此表中。

我在某處讀到SQL Server Services自動處理這個問題,併爲每個會話分配一個會話明細表副本。

是否需要在我的表中添加SPID或自動處理?我是否需要將隔離級別從Read Committed更改爲Serializable?

回答

1

你問的問題的一般答案是,你需要在你的表中有某種類型的會話標識符列,並將每個用戶/會話中的值傳遞給所有存儲過程和/或在該表上運行的SQL語句。

另一種方法是,您可以將隔離級別設置爲Serializable,讓您的用戶排在一個之後,等待所有人都在他們面前完成並讓SQL Server處理它,但這幾乎從來不是您想做。

YourTable

ID  DataCol1 DataCol2 DataCol3 .... User/SessionID 

所以在用戶登錄你的網站/啓動一個會話:

所以粗略,對於第一種選擇,你會喜歡的東西而告終。您使用他們的ID或生成一個SessionID爲他們,並將其傳遞到

StoredProc1ClearSession @UserSessionID  
StoredProc2InsertNewData (AnyOtherParamsYouHave),@UserSessionID 
StoredProc3RetrieveData (AnyOtherParamsYouHave),@UserSessionID 

你明白了。

基本上只要每個SQL語句使用觸摸表有作爲WHERE子句或insert語句的一部分:

UserSessionID or @UserSessionID 

那麼你很可能對你的方式具有檯面,按照您所描述的方式,由多位用戶安全共享。

對於第二個選項,請 read this所以你意識到自己想要的是什麼。 :)

然後把這樣的代碼

CREATE PROC yourstoredproc 
paramaterslisted 
AS 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 
BEGIN TRANSACTION; 

YOURCODE TOUCHING TEMPTABLE HERE 

COMMIT TRANSACTION; 

萬一你不看鏈接:

SERIALIZABLE 指定如下:

這阻止更新或其他交易插入任何符合當前事務執行的任何語句的行。這意味着如果事務中的任何語句再次執行,它們將讀取相同的一組行。範圍鎖定一直持續到事務完成。這是隔離級別最嚴格的原因,因爲它鎖定了整個鍵的範圍並持有鎖直到事務完成。由於併發性較低,因此僅在必要時才使用此選項。此選項與在事務中的所有SELECT語句的所有表上設置HOLDLOCK的效果相同。

+0

第一種方法在此時不可行,因爲需要修改一對存儲過程。改變隔離級別的第二種方法現在看起來很容易。我需要在處理臨時表的存儲過程之上添加什麼語法? – RKh 2011-12-26 08:17:18

+0

我已經更新了我的答案,以解決第二種方法。 – TetonSig 2011-12-26 08:36:10

1

您提到的「每個會話單獨複製」聽起來像快照隔離,默認情況下不啓用。

儘管具體細節在某種程度上取決於您同時進行的其他事務,但一般而言,它應該足夠簡單地將DELETE和INSERT命令包裝在單個事務中。您不應該需要增加隔離級別。

BEGIN TRAN 
DELETE ... 
INSERT ... 
COMMIT TRAN