2010-01-04 32 views
0

我正在將一個webapp從mysql轉換到SQL Server。現在,我想轉換下面的代碼(這是一個簡化版本):如何在SQL Server中像MYSQL一樣鎖定

LOCK TABLES media WRITE, deleted WRITE; 
INSERT INTO deleted (stuff) SELECT stuff FROM media WHERE id=1 OR id=2; 
DELETE FROM media WHERE id=1 OR id=2; 
UNLOCK TABLES; 

因爲我複製這是會被刪除我想,以確保任何讀爲「媒體」或「刪除」的東西將等待整個操作準備就緒。否則,這些讀取將會在稍後看到不再存在的東西。

我怎麼能複製在SQL Server這種行爲?我閱讀了關於事務和隔離級別的一些頁面,但我無法弄清楚是否可以禁用對'媒體'和'刪除'(或行級別)表的任何讀取。

Thanx!

回答

1

您可以在查詢中使用鎖提示。如果您指定一個表鎖並將其保持到事務結束,那應該是等價的。

begin transaction; 

INSERT INTO deleted 
    SELECT stuff FROM media WITH (tablock holdlock) 
    WHERE id = 1 or id = 2; 

DELETE FROM media where id = 1 or id = 2; 

commit; 
+0

感謝名單!我會閱讀鎖定提示。任何教程的建議? – chrizzler 2010-01-05 08:36:38

+0

我更喜歡只使用SQL Books Online。詳細,但完整的參考。它有一些例子。 http://technet.microsoft.com/en-us/library/ms187373.aspx – 2010-01-05 13:39:54

0

作爲一個DB無關的方法,你可以考慮有一個「刪除」或「禁用」欄顯示的結果是否應該返回給用戶。例如,如果列的值不爲零,則可以爲該列使用整數,但不包括用戶視圖中的記錄。所以,相反選擇的,並插入上面,你可以做(​​所有的例子都在MySQL的SQL方言):

UPDATE media SET inactive=1 WHERE stuff=1 OR stuff=2; 

這將不允許用戶查看記錄。然後,您可以在不活動的記錄複製到「已刪除」表,如果需要的話,根據您上次更新非活動記錄的時間從媒體表中刪除:

INSERT INTO deleted (stuff) SELECT stuff FROM media WHERE inactive = 1; 
DELETE from media WHERE inactive <= 1; 

的整數可以用來識別「無效工作「,即」刪除「記錄。

根據您所描述如何架構,這種情況下不完全匹配什麼鎖定的方法,因爲「媒體」表可以在UPDATE語句的執行過程中進行修改。如果存在可用於進一步定義記錄以標記爲非活動狀態的列(例如時間戳),則可以解決(或至少減輕)該問題。