2013-08-22 38 views
4

我們有一些運行時間非常長的ETL包(有些需要運行幾個小時),需要由NServiceBus端點啓動。我們不需要爲整個流程保留單個事務,並且可以將其分解爲更小的事務。由於NServiceBus處理程序將整個事務包裝在一個事務中,所以我們不希望在單個事務中處理它,因爲它會超時 - 更不用說在鎖定DBMS時產生問題。完成任務後,SQL Server 2012(或SSIS)如何通知NServiceBus?

我目前的想法是,我們可以異步產生另一個進程,立即從處理程序返回,並在完成(成功或失敗)時發佈事件。我還沒有找到關於如何將新的NServiceBus 4.0 SQL Server Broker支持與傳統MSMQ傳輸集成的大量文檔。這甚至有可能嗎?

SQL Server 2012(或SSIS包)中的長時間運行進程以異步方式完成時通知NServiceBus訂戶的首選方式是什麼?

+0

nservicebus什麼都不知道,有什麼能阻止你的SSIS包在完成時調用方法/將消息放入隊列嗎? – billinkc

+0

不是我所知道的,我只是問最簡單的方法是什麼。最糟糕的情況是,您可以手動在SSIS中編寫代碼(或者SQL Server中的CLR中的一些託管代碼),以便將消息放入MSMQ隊列中 - 但是,然後,您失去了NServiceBus中的一些功能,可幫助您管理這些功能隊列。 –

回答

5

它看起來是可以做到從SSIS一個HTTP請求,看到How to make an HTTP request from SSIS?

考慮到這一點,你可以使用通過網關發送消息到NServiceBus(網關只是一個HttpListener)向您的發佈告訴它發佈一條消息,通知所有訂閱者長期運行的ETL包已經完成。

要發送一個消息,你需要做的是這樣的網關:

var webRequest = (HttpWebRequest)WebRequest.Create("http://localhost:25898/Headquarters/"); 
webRequest.Method = "POST"; 
webRequest.ContentType = "text/xml; charset=utf-8"; 
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"; 

webRequest.Headers.Add("Content-Encoding", "utf-8"); 
webRequest.Headers.Add("NServiceBus.CallType", "Submit"); 
webRequest.Headers.Add("NServiceBus.AutoAck", "true"); 
webRequest.Headers.Add("NServiceBus.Id", Guid.NewGuid().ToString("N")); 

const string message = "<?xml version=\"1.0\" ?><Messages xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://tempuri.net/NServiceBus.AcceptanceTests.Gateway\"><MyRequest></MyRequest></Messages>"; 

using (var messagePayload = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(message))) 
{ 
    webRequest.Headers.Add(HttpRequestHeader.ContentMd5, HttpUtility.UrlEncode(Hasher.Hash(messagePayload))); //Need to specify MD5 hash of the payload 
    webRequest.ContentLength = messagePayload.Length; 

    using (var requestStream = webRequest.GetRequestStream()) 
    { 
     messagePayload.CopyTo(requestStream); 
    } 
} 

using (var myWebResponse = (HttpWebResponse) webRequest.GetResponse()) 
{ 
    if (myWebResponse.StatusCode == HttpStatusCode.OK) 
    { 
     //success 
    } 
} 

希望這有助於!

+0

我在概念驗證中使用了這個解決方案,並且運行良好。我將發佈一些我需要對此代碼進行的更改,以使其作爲C#CLR過程正常工作並接受此答案。 –

+0

很高興聽到:) –

2

SSIS 2012中實際上有一項任務是將消息放入MSMQ Message Queue Task中。您只需將它指向您的MSMQ連接,並使用表達式自定義您的消息,包名稱,成功/失敗次數,行數等。

取決於我們討論的包的數量以及您想要的定製方式消息是,你最好的選擇是編寫一個獨立的工具,以你想要的任何格式創建消息,然後使用一個執行進程任務來調用該實用程序,使用你想要傳入的包中的任何參數進行格式化信息。

你也可以使用相同的代碼,只是創建一個自定義SSIS任務(輕鬆了許多比它的聲音。)

1

我想過幫堅持DRY原則是使用一個主SSIS包。

在我看來,它看起來像是一個執行包任務,連接到X。將程序包配置爲包名稱參數。配置執行包任務以使用參數來確定要調用的包。

X可能是一個腳本任務,但也許@凱爾黑爾指出,它可能是Message Queue Task。我把這個決定留給那些更熟悉NServiceBus的人。

在我看來,重要的是不要將這個邏輯添加到每個軟件包中,因爲這將成爲維護的噩夢。

相關問題