有沒有辦法通知一個Web服務器(在我的情況下,一個託管在C#中的MVC2 Web應用程序的Web服務器)的事實,有一個數據庫的變化?目的是保持Web服務器緩存與數據庫同步。SQL Server通知Web服務器的表變化
在ASP.NET中有輪詢結構允許這樣做,但我更喜歡推送系統。我也假設數據庫可以被網絡服務器本身以外的元素操縱。
我對SQL Server/ASP MVC的有限訣竅說,有一種方法是通過創建一個表TRIGGER,這個表觸發了一個可以強制更新的網址。
有沒有辦法通知一個Web服務器(在我的情況下,一個託管在C#中的MVC2 Web應用程序的Web服務器)的事實,有一個數據庫的變化?目的是保持Web服務器緩存與數據庫同步。SQL Server通知Web服務器的表變化
在ASP.NET中有輪詢結構允許這樣做,但我更喜歡推送系統。我也假設數據庫可以被網絡服務器本身以外的元素操縱。
我對SQL Server/ASP MVC的有限訣竅說,有一種方法是通過創建一個表TRIGGER,這個表觸發了一個可以強制更新的網址。
SqlDependency
是要走的路,如果變化率適中。對於高變化率,您最好輪詢變更。要了解SqlDependency的工作原理,請閱讀The Mysterious Notification。 ASP已經內置了對SqlDependency的支持,即SqlCacheDependency
。如果可能的話,還有LinqToCache可以將SqlDependency功能添加到任意的LINQ查詢中。
觸發絕對是一個很大的禁忌。你不能讓數據庫事務在一些URL上等待響應,你的性能就會崩潰,基本上什麼都不會。更不用說可用性問題了(如果URL不響應,更新將會失敗,無論出於何種原因)。
您的「SQL Server的有限專門技術」就足夠了。你應該創建一個AFTER INSERT,UPDATE,DELETE觸發器來完成你所需要的。
另一件事是,這是一個壞主意,但你可能知道的..
正確的方法來解決這樣的問題是使用某種消息隊列如的。 MSMQ。
我能想到的唯一方法是編寫一個CLR用戶定義的函數(UDF)並通過感興趣的表上的插入/更新/刪除觸發器來調用它。
UDF應該產生一個線程,通知web服務器並立即返回到觸發器。出於顯而易見的原因,在觸發器或正在運行的事務中調用任何潛在的長時間運行或可能失敗的操作(如訪問網絡)被認爲是非常糟糕的形式。當然,除非您喜歡讓生產DBA的憤怒倒下你喜歡麥克斯韋的銀錘。
我自己沒有經驗,但System.Data.SqlClient.SqlDependency
類看起來像你需要。
根據MSDN:
的SqlDependency非常適用於高速緩存的場景,你的ASP.NET應用程序 或中間層服務需要保持在內存中緩存的某些信息 。 SqlDependency允許您在數據庫中的原始數據發生更改時收到通知 ,以便刷新高速緩存可以 。
要在表內容更改/更新時從數據庫獲取通知,可以使用TableDependency
。
與.NET SqlDependency
的區別在於TableDependency
會引發包含更改/刪除/插入的數據庫表值的事件。
使用SqlDependency
您必須執行select以在任何時間獲取新數據SqlDependency
通知您的代碼數據庫表中的內容已發生更改。
隨着TableDependency
就可以避免因爲你收到事件包含所有被刪除/插入/修改的值:
string conString = "data source=.;initial catalog=myDB;integrated security=True";
using(var tableDependency = new SqlTableDependency<Customers>(conString))
{
tableDependency.OnChanged += TableDependency_Changed;
tableDependency.Start();
Console.WriteLine("Waiting for receiving notifications...");
Console.WriteLine("Press a key to stop");
Console.ReadKey();
}
...
...
void TableDependency_Changed(object sender, RecordChangedEventArgs<Customers> e)
{
if (e.ChangeType != ChangeType.None)
{
var changedEntity = e.Entity;
Console.WriteLine("DML operation: " + e.ChangeType);
Console.WriteLine("ID: " + changedEntity.Id);
Console.WriteLine("Name: " + changedEntity.Name);
Console.WriteLine("Surname: " + changedEntity.Surname);
}
}
好像的SqlCacheDependency(SqlCommand的)就是我要找的,因爲它使得在保證工作交貨。但是,您通過投票優先於查詢通知方法的建議而讓我失去了信心。輪詢的成本是否比檢查所請求的通知查詢是否受到某些插入/更新/刪除操作所需的測試效率高一倍? –
發送通知的成本很大。如果您僅通過高速更改立即通知無效通知,則最好直接檢查該值。這是一個很好的線,其中輪詢效果更好的點因應用程序而異,從表到表也不盡相同。您必須在重負載下測量並觀察一個與另一個的影響。 –