简体   繁体   English

与JMS(ActiveMQ)一起使用事务

[英]Using transactions with JMS (ActiveMQ)

In our backend there are several services that send and receive messages via JMS with Apache ActiveMQ. 在我们的后端,有几个服务通过JMS与Apache ActiveMQ发送和接收消息。 Each service has a single session to the ActiveMQ broker. 每个服务都有一个到ActiveMQ代理的会话。 We now want to do the following (pseudo code): 我们现在想要执行以下操作(伪代码):

Service s1: 服务s1:

Message m = createMessage("s2","Hello World")
sendMessage(m)
try {
   Message answer = commit()
   ...
} catch (TransactionFailedException e){
   ...
}

Service s2: 服务s2:

onMessageReceive:
try {
   Message m = getReceivedMessage()
   Message answer = doSomeStuff()
   send(answer)
} (Exception e) {
   rollback()
}

The commit obviuosly has to block until the answer arrives or the transaction failes. 提交显然必须阻止,直到答案到达或交易失败。 It should also be possible that service s2 creates a new nested transaction because s2 is sending a message to another service. 服务s2也应该可能创建一个新的嵌套事务,因为s2正在向另一个服务发送消息。 How can transactions from ActiveMQ be used to achieve this behaviour? 如何使用ActiveMQ的事务来实现这种行为? There are some examples available but in these examples transactions are merely used as a batch mechanism to send messages. 有一些示例可用,但在这些示例中,事务仅用作发送消息的批处理机制。

I'm interpreting you question to mean that you want a failure of work in s2 to cause an ongoing transaction in s1 to be rolled back. 我正在解释你的问题意味着你希望s2中的工作失败导致s1中的正在进行的事务被回滚。

So you want 所以你要

s1 do some work

s2 do some work

if ( s2 OK )
   perhaps do even more work in s1
   commit s1
else
   rollback s1

The asynchronous model of JMS is not classically designed for this purpose. JMS的异步模型不是为此目的而经典设计的。 The fundamental reason is because 根本原因是因为

  1. During a transaction resources (eg database records) are locked - s1 has done some work, until the transaction has resolved those resources must be kept locked. 在事务资源(例如数据库记录)被锁定期间 - s1已完成一些工作,直到事务已解决,这些资源必须保持锁定状态。
  2. Asynch processing is designed to decouple s2 work from s1 work, s2 work might happen many minutes or indeed days after the request was placed on the queue. Asynch处理旨在将s2工作与s1工作分离,s2工作可能在请求放入队列后几分钟或几天内发生。 S2 can't know whether or not s1 is still waiting for him. S2无法知道s1是否还在等他。 The whole design point of JMS is to decouple processing in s1 and s2. JMS的整个设计点是在s1和s2中解耦处理。

There are two approaches to achieving coordination between s1 and s2: 有两种方法可以实现s1和s2之间的协调:

One is to use true distributed transactions, using a protocol other than JMS, for example EJBs can propagate transactions from one process to another, or use WS-AtomicTransaction and web Services. 一种是使用真正的分布式事务,使用除JMS之外的协议,例如EJB可以将事务从一个进程传播到另一个进程,或者使用WS-AtomicTransaction和Web服务。 This does add operational complexity - you have to manange transaction logs and scenarios where you have a long-term failure of one component. 这确实增加了操作复杂性 - 您必须管理事务日志和一个组件长期失败的情况。

The alternative is to design the two cooperating systems to robustly handle "compensating" work. 另一种方法是设计两个协作系统,以稳健地处理“补偿”工作。 You accept that, for example s2 may fail, and have secondary processing to deal with resending requests, dealing with timeouts etc. In the end you may come down to some situations where humans need to be involved, but with good design these situations can be minimal. 你接受这一点,例如s2可能会失败,并且有二次处理来处理重发请求,处理超时等。最后你可能会遇到人类需要参与的某些情况,但如果设计良好,这些情况可能是最小的。 In large scale systems there's often no alternative to this, for example an airline's booking system and a hotel chain's booking system may well not be designed for distributed transaction coordination so there's no alternative to having some careful processing to manage reserving flights and rooms. 在大型系统中,通常没有替代方案,例如航空公司的预订系统和连锁酒店的预订系统可能不适合分布式交易协调,因此除了经过一些精心处理以管理预订航班和房间之外别无选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM