2010-01-28 43 views
14

我有一個要求,不斷監視數據庫行以檢查更改(更新)。如果其他來源有更改或更新,則應在我的應用程序中觸發事件(我正在使用WCF)。有什麼方法可以連續監聽數據庫行的變化嗎?需要C#/ SQL數據庫偵聽器幫助

我可能有更多數量的事件來監視同一個表中的不同行。在性能的情況下是否有任何問題。我使用C#web服務來監視SQL Server後端。

回答

5

前段時間我有一個非常類似的需求,我使用CLR SP將它解壓縮到消息隊列中。爲了簡化部署,我創建了一個名爲SendMessage的小函數CLR SP,它只是將消息推入Message Queue,並使用AFTER INSERT觸發器(正常觸發器,不是CLR觸發器)將其綁定到我的表中, 。

在這種情況下,性能是我的主要關注點,但我已經對它進行了壓力測試,並且大大超出了我的預期。與SQL Server Service Broker相比,這是一個非常易於部署的解決方案。 CLR SP中的代碼也非常簡單。

9

您可以在各個表上使用AFTER UPDATE觸發器將項目添加到SQL Server Service Broker隊列中。然後將排隊的通知發送到您的Web服務。

另一個海報中提到的SqlDependency,這也是我想提的,但MSDN文檔,它提供了windows客戶端的例子有點怪,但也提供了這樣的建議:

的SqlDependency被設計用來 在ASP.NET或中間層服務 其中有一個相對較小的 數量的服務器具有對數據庫活動的依賴性 。這是 不適用於客戶端 應用程序,其中數百或 成千上萬的客戶端計算機將 SqlDependency對象設置爲 單個數據庫服務器。

Ref

+0

在我的情況下,我沒有直接訪問數據庫,但可以訪問數據庫中的表。在我的情況下,經紀人隊列仍然有意義嗎?我需要的是一種輪詢特定表格以進行更改(插入,更新,刪除)的方法,然後將事件作爲結果發送,以便隨後進行進一步處理。 我考慮了CLR函數的概念,或者在成功插入/更新/刪除表中的數據後調用服務的類。在這種情況下甚至是好的嗎? – Kobojunkie 2010-01-28 13:41:41

+0

要編寫SQL-CLR,您需要直接訪問數據庫本身。事實上,你是自相矛盾的?! – 2010-02-23 18:21:22

2

監測「持續」可能意味着每隔幾小時,幾分鐘,幾秒甚至幾毫秒。此解決方案可能無法用於毫秒更新:但是如果您只需每分鐘「監視」一次表格,則可以只通過外部進程檢查表進行更新。 (如果存在DateTime列)。然後,您可以處理更改或新添加的行並執行任何需要的通知。所以你不會聽更改,你會檢查他們。以這種方式進行檢查的一個好處是,如果在給定的時間量內更新很多行,那麼您將不會承擔性能問題的風險,因爲您將它們放在一起(而不是響應每個行和每一個單獨更改。)

2

我沉吟了CLR函數 或調用 服務成功後 插入/更新/刪除從 數據表之類的東西的想法。這在 的情況下甚至還好嗎?

也許這不是一個好主意,但我想它還是比進入表觸發地獄更好。

我假設你的問題是你想在每次數據修改之後做一些事情,比如說,重新計算一些值或其他值。讓數據庫負責這不是一個好主意,因爲它可能會對性能產生嚴重影響。

你提到你想檢測插入,更新和刪除不同的表。按照你所傾向的方式來做,這將需要你爲每個表設置三個觸發器/ CLR函數,並讓他們向你的WCF服務發佈一個事件(甚至在sql服務器內可用的.net子集中也支持該事件)。 WCF服務根據收到的事件採取適當的行動。

更好的解決方案是將檢測數據修改的責任從數據庫移到應用程序。這實際上可以非常簡單和有效地實現。

每個表都有一個主鍵(int,GU​​ID或其他)和一個時間戳列,指示條目最後更新的時間。這是一個在樂觀併發場景中經常會看到的設置,所以甚至不需要更新模式定義。但是,如果需要添加此列並且無法卸載使用數據庫將時間戳更新到應用程序,則只需爲每個表編寫一個更新觸發器,並在每次更新後更新時間戳。

爲了檢測修改,您的WCF服務/監控應用程序會在給定的時間間隔內使用主鍵/時間戳對創建本地字典(最好是散列表)。在數據庫中使用覆蓋索引,這個操作應該非常快。下一步是比較兩本詞典和voilá,你去哪兒了。

雖然這種方法有一些注意事項。其中一個是每個表的記錄總和,另一個是更新頻率(如果它太低,則效率低),另一個重點是如果您需要訪問修改/插入之前的數據。

希望這會有所幫助。

1

爲什麼不使用SQL Server通知服務?我認爲這是你正在尋找的確切的東西。閱讀通知服務的文檔,看看是否符合您的要求。

0

我認爲這裏有一些很棒的點子,從可擴展性的角度來看,我認爲外部支票(例如Paul Sasik的回答)可能是迄今爲止最好的(對他來說是+1)。

如果出於某種原因,您不想將檢查外部化,那麼另一個選擇是使用HttpCache來存儲觀察者和回調。

簡而言之,將記錄放入要觀看的數據庫中時,還可以將其添加到緩存中(使用.Add方法)並在其上設置SqlCacheDependency,並調用任何您想要的邏輯調用何時調用依賴項以及該項是從緩存中彈出的。