2014-03-07 40 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