2014-10-07 52 views
5

我有一個包含我的Windows服務應該處理的,關閉時間戳,我想知道我有什麼替代輪詢這樣替代輪詢MSSQL表

SELECT * 
FROM mydb 
WHERE SYSUTCDATE() >= timestamp 

我表計劃任務MSSQL表d可能需要至少每5秒輪詢一次表格。基本上我希望我的Windows服務在表中由時間戳設置的時間處理數據。

對我來說這似乎並不是最有效的方法。我已經研究過DML & CLR觸發器,我不認爲他們會工作,因爲他們會在數據更改時觸發,而不是當時間戳已經過去。思考?


更新2:

我已經意識到,把它稱爲「計劃任務」是措辭的一個糟糕的選擇,所以我會盡力來形容它的更多細節。

該項目的目標是根據我們的業務邏輯發送電話通知給人們。一種情況是應該根據內部事件在特定時間打電話給多個人。根據接聽電話的方式,可以多次呼叫同一個人。因此,爲了簡化事情並消除管理每個電話狀態的複雜性和開銷,我認爲通過將每個電話作爲表中的條目來預先安排每個電話將是個好主意。當通知應該停止時,待處理的電話將從表格中刪除。這將保持Windows服務的設計非常簡單。它所要做的就是根據表格中的時間戳發送通知。


更新1:

消息隊列

我還沒有想出發件人將如何將消息到隊列中在適當的時間。

的SqlDependency

我使用的示例代碼從Detecting Changes with SqlDependency有一個問題。出於某種原因,OnChange事件最初只會被觸發,以後什麼都不會發生。

更新:我不認爲SqlDependency將工作,因爲表中的數據不會改變,使觸發器觸發。

void Initialization() 
{ 
    // Create a dependency connection. 
    SqlDependency.Start(connectionString, queueName); 
} 

void SomeMethod() 
{ 
    // Assume connection is an open SqlConnection. 

    // Create a new SqlCommand object. 
    using (SqlCommand command=new SqlCommand(
     "SELECT timestamp,othercolumn FROM mydb WHERE SYSUTCDATE() >= timestamp", 
     connection)) 
    { 

    // Create a dependency and associate it with the SqlCommand. 
    SqlDependency dependency=new SqlDependency(command); 
    // Maintain the refence in a class member. 

    // Subscribe to the SqlDependency event. 
    dependency.OnChange += new OnChangeEventHandler(OnDependencyChange); 

    // Execute the command. 
    using (SqlDataReader reader = command.ExecuteReader()) 
    { 
     // Process the DataReader. 
    } 
} 
+7

您是否考慮過使用消息隊列? – recursive 2014-10-07 21:52:28

+3

嘗試SqlDependency:http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx – 2014-10-07 21:57:44

+2

您是否考慮將這些轉換爲作業並通過SQL Server代理運行它們? – 2014-10-07 21:57:56

回答

3

好的,首先,考慮不要這樣做。把所有有用的工作都放到配置在數據庫中的週期性任務中去,是一種脆弱的設計,當有人錯誤地配置了某些東西時(容易做到,因爲需要相當先進的觸發器來檢查日程安排的一致性),這種設計很容易中斷,當任務實際上有隱藏的依賴關係時(如果A沒有在B之前運行一段時間,東西被打破,那樣的事情),創建一個難以理解的系統。資料來源:在三家不同的公司和三種不同的平臺/技術中使用三種此類系統的個人經驗,並且不知何故它們都遭受同樣的問題,所以顯然它是一件事情。考慮只是用一個配置文件寫出你想要安排爲普通舊代碼的東西。當然,它不會像通用一樣,但需要維護它的人會感謝你,特別是當他們的需求變得更加複雜時。

SqlDependency即使您確實有一個支持的查詢,也會變得非常易變,並且不易使用。就你所看到的而言,它不起作用,因爲數據庫引擎不會發布通知,除非數據實際發生變化 - 查詢結果隨着時間的推移而改變並不重要。正如尼克指出的那樣,每5秒輪詢一次數據庫通常都很好。這產生可以忽略不計的負載,只要你在mydb.timestamp上創建了一個索引(並且你創建這個非常重要,因爲每5秒執行一次表掃描是而不是 OK)。

唯一的異議是延遲:如果計劃的任何更新必須比每5秒更早一次發生,則輪詢不夠好。在這種情況下,您可以使用Service Broker,並在發生更改(可能來自觸發器)的時刻發送通知給隊列。實際上,SqlDependency在封面上使用了相同的方法,因此您可以創建一個依賴SELECT * FROM table以獲取通知,只要任何表中的內容發生更改,然後執行實際查詢以獲取所需內容(可能找不到任何內容)。但是要小心:獲取正確的代碼而不會被多個快速更新弄糊塗,或者連接中斷不是微不足道的,可能不值得,而不是定期重新加載。

+0

感謝您的詳細回覆。我對數據庫中的所有任務進行預先調度的理由是因爲我認爲這會簡化事情,因爲以編程方式管理它會有太多開銷。我會在我的OP中提供更多信息。 – user3811205 2014-10-14 19:13:55