2012-04-27 33 views
1

我使用Oracle ODP.Net來入隊和出隊。。自動出隊連接

方法A:排隊 方法B:與出隊事件MessageAvailable

如果過程A和B都在運行,就沒有問題。在「流程B」中,事件總是被解僱。

但是,如果「進程B」處於關閉狀態且「進程A」處於開啓狀態,則當「進程B」重新啓動時,在關閉時間插入的隊列將丟失。

是否可以選擇爲過去插入的所有隊列啓動事件?

非常感謝

回答

2

似乎有是解決此問題的兩種方法:

  1. 調用OracleAQQueue類的監聽()方法來撿(註冊爲消息通知後),「孤立」消息坐在隊列中。請注意,Listen()阻塞直到收到消息或發生超時。所以,如果沒有消息在隊列中,你會想要指定一個(短)超時返回到處理線程。
  2. 調用Dequeue()方法並捕獲Oracle錯誤25228(沒有可用於出隊的消息)。請參閱Oracle支持論壇的以下主題:https://forums.oracle.com/forums/thread.jspa?threadID=2186496

我在這個話題上一直在撓頭。如果您仍然需要「手動」測試新消息,首先使用MessageAvaiable事件回調有什麼好處?我思考的一條路線是將Listen()方法封裝在異步調用中,以便調用者不會阻塞該線程(直到收到消息或發生超時)。我在自定義Receive()方法中封裝了Listen()和Dequeue(),並創建了自己的MessageReceived事件處理函數,以將消息細節傳遞給調用線程。似乎有點多餘,因爲ODP.NET提供了開箱即用的回調,但我不必處理您描述的問題(或編寫代碼以「手動」測試「孤立」的消息。對方法的意見/想法是歡迎的

0

我一直在看這個,也結束了做一些類似於格雷格我沒有使用Listen()方法,雖然我不認爲它提供我什麼都超過簡單的Dequeue() - Listen()似乎是有益的,當你想代表多個消費者聽,這在我的例子中是不相關的(見Oracle Docs

因此,過程B'我首先註冊在啓動輪詢過程以檢查任何現有消息之前發送通知。它不聽(),它只是在一個控制的循環內調用Dequeue(),並設置了幾秒鐘的等待週期。如果輪詢過程遇到Oracle超時,則等待期已過,並停止輪詢。如果等待期沒有過期,我可能需要考慮處理超時(儘管不是100%確定這是否可能發生)。

我注意到,在輪詢期間排隊的任何消息都會調用消息通知方法,但在連接時嘗試檢索該輪詢過程似乎總是採用的消息。因此,在消息通知方法中,我捕獲並忽略了任何編號爲25263(no message in queue <...> with message ID <...>)的OracleException。