2012-05-18 78 views
3

這是Is it possible to force row level locking in SQL Server?的擴展。這裏是用例我需要行級鎖定

我有賬號表有賬號,餘額等。這張表正被許多應用程序使用。當我修改某個帳戶時,其他人正在修改另一個帳戶。所以預期的行爲是我會鎖定我的賬戶(ROW),另一個使用會鎖定他(另一個ROW)。

但SQL Server 2008 R2將此鎖定升級爲page/table,第二個用戶獲取超時異常。我已經嘗試了所引用問題中提到的所有解決方案,但沒有任何工作。

如何強制SQL Server鎖定行級鎖或者如何修改此模型以便與頁/表鎖定配合使用?

編輯 更新是通過其PK針對單個記錄,並將其編入索引,以便只有一行被更新/鎖定,這一過程需要不超過一分鐘

更多修改 現在看起來奇怪的事情正在發生。我正在爲打開多個連接的DAL使用ORM庫,並且我已經向他們的支持提出了問題。但是,爲了測試目的,我打開了兩個會話查詢工具,並確實如下

Session # 1 
begin tran 
UPDATE myTable SET COL_1 = COL_1 WHERE COL_1 = 101; 

Session # 2 
SELECT COL_1 FROM myTable WHERE COL_1 = 101; 

會話#2中的查詢超時了!其他值爲COL_1的查詢正在正常工作。現在看起來,如果同一記錄在另一個會話中處於編輯模式,SELECT會被阻塞。

儘管Oracle在其他會話正在修改時支持選擇一行(使用默認參數/無關鍵字),但SQL Server不會(具有默認參數/無關鍵字),所以看起來問題在於圖書館。

+0

你期望這張表有多少總記錄?你有多少用戶在你的網站? – Nilish

+0

現在我正在測試兩個用戶,並沒有。的記錄是13000.我的測試甚至在單次更新上失敗了,但我將鎖定7條記錄。 – bjan

+1

如果你真的只用一個更新來鎖定**單行**,那麼第二次更新也只針對單行就可以正常工作。在你的SQL Server中肯定還有其他事情發生,或者你可能有錯誤的排序配置...... –

回答

8

默認情況下,SQL Server總是使用行級鎖定。那麼究竟是什麼,你需要?

如果你鎖定超過一定數量的行(大約5000),那麼SQL Server將執行lock escalation(鎖定表而不是超過5000行),以優化性能和優化資源使用情況 - 但這是一個很好的事情! :-)

有些方法可以完全關閉 - 但這些都是不推薦!,因爲你正在搞亂SQL Server存儲引擎中的一個非常基礎的機制。

參見:

+0

我正在做一個虛擬更新來鎖定記錄,而這個虛擬更新正在使用主鍵字段。當我嘗試更新另一個會話中的另一個記錄時,它一直在等待......是行級鎖定! – bjan

+0

**如果你鎖定超過一定數量的行(大約5000),那麼SQL Server將執行鎖升級(鎖定表,而不是超過5000行)**所以一旦工作完成。鎖將被釋放。自動或我們必須手動進行? – Nilish

+0

當事務完成(或回滾)時,SQL Server將釋放涉及的鎖 –

2

將您的系統設想爲客戶端 - 服務器應用程序,其中客戶端和服務器通過非常慢的線路連接(例如,蝸牛郵件),並且用戶正在修改th eir記錄很長時間(例如一週)。然後考慮一下,當你需要鎖定行/數據,以及實際上允許更改行/數據等時 - 顯然將SQL服務器內部鎖定放置幾天似乎不再是個好主意。

如果您沒有這種情況,當兩個用戶需要更改相同的記錄時,您完全不需要鎖定數據。當數據庫中的記錄更改時 - 換句話說,當用戶提交更改時,您只需要鎖定很短的時間。 (這是樂觀鎖定方案。)當然,如果兩個用戶改變相同的數據,那麼最新的改變將覆蓋更早的改變。

如果您絕對要求兩個用戶永遠不要修改相同的數據(悲觀鎖定),那麼可能最通常的方法是在數據表中使用某些應用程序定義的鎖表或特定字段。當一個用戶檢查某個記錄(當開始編輯或類似時),那麼你需要檢查,該記錄是否已被使用(鎖定),如果沒有,然後將該記錄標記爲鎖定。當然,你需要一些功能來刪除陳舊的鎖。

或者對這種情況使用SQL Server內部特定函數。看這裏:sp_getapplock function in MSDN;這種方式你不應該擔心永久鎖定的記錄等。

+1

再次,如果您單獨鎖定超過5000行,則整個表將被鎖定 – Nilish

+2

我建議不要在此方案中使用SQL鎖定,但會創建自定義邏輯。我們已經完成了我們的財務應用程序 - 用戶經常開始編輯文檔並在點擊Ctrl + S之前進行午餐:) – Arvo

+1

我正在鎖定一行,並且它將不到一分鐘,而其他用戶正在鎖定另一行。無論我需要一分鐘還是10分鐘,其他用戶都不應該等待,因爲他正在鎖定另一條記錄 – bjan