GO
SQL Server 2005中的存儲過程并發問題
我在SQL Server2005中遇到了并發問題。我持有車票的公共汽車上有一些空閑的座位。我在插入銷售的查票之前,需要查看是否還有空閑的座位。我的存儲過程做的事情如下所示:
CREATE PROCEDURE add_ticket — parameters
DECLARE free_seats int BEGIN TRANSACTION SELECT free_seats
= COUNT(*) FROM tickets WHERE seat_is_not_taken IF free_seats
<> 0 INSERT INTO tickets VALUES(…) — some other statements END TRANSACTION
問題就是兩個過程可以同時讀取空閑票數,并且都可以預約一張票,即使是那里已經沒有空余的了。我需要一種方法來防止一個過程在另一個過程運行add_ticket程序,但是還沒有插入一張新票的時候讀取空票的數量。
回答:
你是正確的;更高的隔離級別也不會保證多個讀者去同時去讀取同一個數據行。然而,還有幾種方法你可以完成這項工作。例如,你可以給每個座位分配一個惟一的標識符(意思是,惟一鍵——不一定是GUID),并且創建一個描述哪些座位已經被預訂了的表。在表上放一個 UNIQUE約束,你就可以確保同一個座位不會被插入兩次了。
就是說,我認為一個更有趣的方法就是使用SQL Service Broker。你可以為每個公交建立一個會話,并且將這個會話的句柄存放在一個表中,讀者在執行RECEIVE之前可以參考這個表。通過這種方式,讀者就可以正確地過濾。公共汽車上的每個座位都插一個消息到隊列中。讀者就可以簡單地RECEIVE到所需的消息(在這個過程中,預定公共汽車上的座位)。 Service Broker會確保沒有消息會被接受兩次,也就是說你不會再遇到并發問題了。
文章來源于領測軟件測試網 http://www.kjueaiud.com/