Andriy Kryvtsun Andriy Kryvtsun - 1 month ago 13
Java Question

Appropriate EIP selection for sequential subflow calls

In Spring Integration I need to send a message sequentially to subflow A (it stores the message into DB) and then to subflow B (it uses some DB lookup). Whole A and B execution should be performed in the boundary of one transaction.

Initially, Publish-Subscribe Channel with 2 subscribers for A and B in one thread was used. However, there are 2 drawbacks


  1. there is no guaranteed order of subscribers execution

  2. it's easy to add
    task-executor
    attribute to the channel. Thus, A and B will be executed in parallel in different threads and, thus, in different transactions.



So, what EIP is better to use here?

I'm thinking about Recipient List Router but, again, can't see guaranty of a message sending order for recipients.

Answer

There is an order attribute on the AbstractMessageHandler which guaranties how subscribers will be subscribed to the PublishSubscribeChannel: http://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#channel-implementations-directchannel:

The order is determined by an optional order value defined on the handlers themselves or, if no such value exists, the order in which the handlers are subscribed.

If a certain situation requires that the dispatcher always try to invoke the first handler, then fallback in the same fixed order sequence every time an error occurs, no load-balancing strategy should be provided. In other words, the dispatcher still supports the failover boolean property even when no load-balancing is enabled. Without load-balancing, however, the invocation of handlers will always begin with the first according to their order. For example, this approach works well when there is a clear definition of primary, secondary, tertiary, and so on. When using the namespace support, the "order" attribute on any endpoint will determine that order.

Also source code of AbstractDispatcher:

private final OrderedAwareCopyOnWriteArraySet<MessageHandler> handlers =
        new OrderedAwareCopyOnWriteArraySet<MessageHandler>();

Also an order XML attribute description:

    <xsd:attribute name="order" type="xsd:string">
        <xsd:annotation>
            <xsd:documentation><![CDATA[
Specifies the order for invocation when this endpoint is connected as a
subscriber to a channel. This is particularly relevant when that channel
is using a "failover" dispatching strategy. It has no effect when this
endpoint itself is a Polling Consumer for a channel with a queue.

                ]]></xsd:documentation>
        </xsd:annotation>
    </xsd:attribute>