2014-03-07 76 views
2

我已經使用Netty 4編寫了一個SMPP 3.4消息傳遞系統。一旦我接收到一個新的消息提交(submit_sm數據包),我很樂意接受該平臺,我會寫回一個smpp響應然後將接受的消息寫入本地持久隊列(例如可能是數據庫)。在Netty消息處理中使用JDBC事務

假設JDBC爲本示例的消息存儲區;持久性和一致性是關鍵,儘管我無法將JDBC插入和SMPP套接字寫入事務,但我至少想要在smpp響應channel.write操作失敗時回到JDBC插入。

我目前的做法是維護一個新的線程池,該線程池在單個線程中處理JDBC插入和SMPP響應。首先,我將消息插入數據庫,然後調用channel.writeAndFlush()。awaitUninterruptibly()以檢查操作是否成功完成。如果操作失敗,我可以回滾數據庫事務。

這似乎是正確的方法嗎?我無法在ChannelFuture上使用ChannelFutureListener,因爲我需要保留在同一個線程中,以免破壞事務邊界。我認爲在我的方法中,必須從選擇的IO線程和阻塞IO操作結果的線程進行一些通信?

所有最優秀的

喬恩

回答

3

調度接收到的請求到另一個線程池來處理一個JDBC事務,並從JDBC線程中調用channel.write*()是完全沒有問題。

有一點需要記住的是,即使您的寫作未來得到滿足,對方也可能沒有收到您的回覆。完成的寫作將來只會告訴你,操作系統接受了你的寫入請求。 O/S的TCP/IP堆棧將盡最大努力將響應發送給對等方,但如果連接永久中斷,它最終將失敗。

在這種情況下,客戶端可能會重新嘗試請求,並且會導致重複的事務。爲了避免這種情況,通常每個請求都有一些標識符,服務器會保留最近的請求ID列表以拒絕重複的請求。

+0

謝謝,非常有幫助,特別是關於寫未來的部分。 – jdh961502

+0

我的榮幸。不要忘記標記爲已回答。 :-) – trustin