2008-10-30 57 views
4

有一個小型系統,其中一個數據庫表作爲MSSQL 2005上的隊列。多個應用程序正在寫入此表,並且一個應用程序正在以FIFO方式讀取和處理。並行處理數據庫隊列

我必須讓它更先進一點才能創建一個分佈式系統,其中可以運行多個處理應用程序。結果應該是2-10處理應用程序應該能夠運行,並且他們不應該在工作中互相干擾。

我的想法是擴展隊列表,顯示一個進程已經在處理它。處理應用程序將首先用它的idetifyer更新表,然後詢問更新的記錄。

因此,像這樣:

start transaction 
update top(10) queue set processing = 'myid' where processing is null 
select * from processing where processing = 'myid' 
end transaction 

處理後,將表格別的東西的處理列,例如「完成」,或什麼的。

我對這種方法有三個問題。

第一:可以以這種形式工作嗎?

第二:如果它工作,它有效嗎?你有任何其他想法來創造這樣的分佈?

第三:在MSSQL中,鎖定是基於行的,但在鎖定了一定數量的行之後,鎖被擴展到整個表。所以第二個應用程序不能訪問它,直到第一個應用程序不釋放事務。爲了不鎖定整個表格,只能創建行鎖,可以選擇多大(頂部x)?

回答

6

這是可行的,但你可能會發現你會遇到阻塞或死鎖,其中多個進程嘗試讀取/更新相同的數據。我編寫了一個程序來爲我們的一個系統完成這個操作,它使用了一些有趣的鎖定語義來確保這種類型的事物在沒有阻塞或死鎖的情況下運行,described here

+0

這是非常好的,正是我所需要的。謝謝。 – Biri 2008-10-30 09:12:03

+0

不錯。我說我會感興趣;-) – philsquared 2008-10-30 09:35:29

1

這種方法對我來說看起來很合理,而且與我以前使用的方法類似 - 成功。

此外,行/表只會在更新和選擇操作發生時被鎖定,所以我懷疑行vs表問題確實是一個主要考慮因素。

除非您的應用程序的處理開銷太低以至於微不足道,否則我會保持「最高」值較低 - 可能只有1個。當然,這完全取決於您的應用程序的細節。

說了這麼多,我不是一個DBA,因此也將擁有更多的專家解答

1

關於你關於鎖定的問題。您可以使用鎖定提示強制它僅鎖定行

update mytable with (rowlock) set x=y where a=b 
1

此方法的最大問題是您增加了對該表的「更新」數量。試試這隻需要一個進程(更新+刪除)和其他人在表中插入數據,你會發現在大約一百萬條記錄中,它開始崩潰。

我寧願有一個消費者用於數據庫,並使用消息隊列將處理數據傳遞給其他消費者。