2012-10-20 52 views
0

我有一個具有遠程數據庫(MsSql)和多個Windows/Web客戶端的自動化項目。客戶端應用程序檢查並在表上選擇合適的行,並將其標記爲保留在該行上進行操作。更新事務中的選定行

  1. 如何在另一客戶端選擇同一行之前輕鬆獲取值並更新所選行?我有什麼選擇呢?
  2. 如果我想在事務塊內部執行多個select-update語句(對於不同的表),我可以使用TransactionScope作爲此目的嗎?

編輯: 讓我們來想象一個電影票系統(我的電影票有點複雜)。用戶選擇座位併購買票據。我想爲這位用戶預留座位兩分鐘,以便有足夠的時間購買。兩分鐘後,其他人也可以使用。在更新行之前,我運行選擇查詢來查找第一個空位。我的問題是關於同一用戶的select和update語句之間的一段時間。我想要防止:用戶1的選擇語句運行,並且此時用戶2在用戶1預留座位之前運行相同的選擇。

+0

這可能感興趣的:HTTP:// www.codeproject.com/Articles/114262/6-ways-of-doing-locking-in-NET-Pessimistic-and-opt#How%20can%20we%20do%20pessimistic%20locking – JohnLBevan

回答

2

既然你想鎖定和執行實際行動之間的用戶輸入,然後

update top (1) seats 
set time_locked = getdate(), user_locked = <the site user> 
output inserted.seat_id, inserted.time_locked, inserted.user_locked 
where <your conditions> and time_locked is null 

在這種情況下,你不」在執行此操作之前,請先啓動事務,因爲您要立即提交更改。只要您鎖定某一行,或者在稍後的時間點,您可以稍後再開始轉換。

如果你從一個事務中做到這一點,那麼其他進程將等待,直到你提交該事務,所以你將不會得到任何併發。您將看到的是,一個過程正在工作,所有其他人在等待。

當以後再回到鎖定行,你確認time_locked仍然非空,誰鎖定用戶相同的用戶:

update seats 
set totally_taken = 1 
where 
    seat_id = <remembered seat id> 
    and time_locked = <remembered time_locked> 
    and user_locked = <remembered user_locked> 
+0

感謝您的回答。我認爲第一個解決方案就足夠了,但是如果我在TransactionScope中放置一個選擇和更新查詢,會發生什麼?這足以實現沒有updlock,rowlock,readpast的結果嗎? – aliassce

+0

@aliassce我根據您的編輯刪除了不相關的答案部分。查詢將同時更新和選擇。你可以把它包裝到一個交易中,但你不必這樣做,因爲無論如何您都必須立即提交它。 – GSerg

+0

我想了解的是,transactionScope會在所有其他客戶端完成或回滾之前訪問相同的表嗎? – aliassce

0

如果你使用的是SQL Server,你可以在你的select中做一個ROWLOCK。

SELECT * FROM與ROWLOCK訂單WHERE狀態= '待定'