2012-10-02 89 views
0

在樂觀方法的例子中,@version(例如程序中的參數)總是預先知道的。 是否可以在程序中接收@version以及它可能會影響什麼。程序 部分:這是一個樂觀的方法嗎?

CREATE PROCEDURE [dbo].[UpdateTestTable2] 
... 
SELECT @version = [version] 
FROM dbo.TestTable2 
WHERE Id = @Id 

BEGIN TRANSACTION 

UPDATE dbo.TestTable2 
SET testName = @testName 
WHERE Id = @Id AND [version] = @version 
... 
+3

又是什麼問題? – RichardTheKiwi

+0

@Richard aka cyberkiwi我的方法是否樂觀併發? –

+0

SP中的第一個查詢是多餘的。 –

回答

3

「版本」需要來自應用程序,反映已選擇要更新記錄的版本。然後將此信息作爲更新的一部分,以確保更新正在「正在查看」的記錄的相同版本。

這就是你似乎通過提供一些來自外部的信息(在這種情況下@id)。但是,正如伊戈爾指出的那樣,對於名爲「版本」的列沒有什麼魔力:您可以放棄第一個選擇並使用@id離開過濾器。

但是...你缺少的是同時更新的版本/ ID字段。你應該做smoething這樣的:

update testtable2 
set versioning_column += 1 
where versioning_column = @versioning_column 

這樣一來,要更新正是你打算列,但在同一時間排除任何人通過改變版本戳這樣做別的。

+0

解釋爲什麼無法在過程中接收行的版本? –

+1

@Alexander:因爲在proc中,你無法知道應用程序所看到的行的版本:如果另一個進程已更新它們,它們可能已經陳舊 – davek

+2

'set versioning_column + = 1'已足夠,因爲'WHERE '子句保證增量只在正確的應用程序行版本上發生。 –

0

實現樂觀併發的一種簡單方法是在讀取數據時計算哈希值,然後在保存新數據之前對該表重新計算該值:如果哈希值不同,則在讀取和寫入操作之間修改該表。

CREATE TABLE #TMP(name VARCHAR(10), age TINYINT); 
INSERT #TMP VALUES ('Ann', 10); 
INSERT #TMP VALUES ('Ann', 10); 
INSERT #TMP VALUES ('Ann', 20); 
INSERT #TMP VALUES ('Beth', 10); 
SELECT *, CHECKSUM(*) AS [hashvalue] FROM #TMP 

-- name  age hashvalue 
-- ---------- ---- ----------- 
-- Ann  10 940063178 
-- Ann  10 940063178 
-- Ann  20 940063188 
-- Beth  10 1206720504 
相關問題