Transaction completion not deterministic
<p>My flow setup looks like this:</p>

<pre><code>&lt;int:channel id="channel1"&gt;
    &lt;int:queue/&gt;
&lt;/int:channel&gt;
&lt;int:channel id="channel2"&gt;
    &lt;int:queue/&gt;
&lt;/int:channel&gt;

&lt;int:chain id="chain1" input-channel="channel1" output-channel="channel2"&gt;
    &lt;int:poller&gt;
        &lt;int:transactional propagation="REQUIRES_NEW"/&gt;
    &lt;/int:poller&gt;
    &lt;Authorzier/&gt;
    &lt;JMS_put1/&gt;
    &lt;DB_update_state1/&gt;
&lt;/int:chain&gt;

&lt;int:chain id="chain2" input-channel="channel2" output-channel="nullChannel"&gt;
    &lt;int:poller&gt;
        &lt;int:transactional propagation="REQUIRES_NEW"/&gt;
    &lt;/int:poller&gt;
    &lt;Transformer/&gt;
    &lt;JMS_put2/&gt;
    &lt;DB_update_state2/&gt;
&lt;/int:chain&gt;
</code></pre>

<p>Now in some cases the the transaction of chain2 completes before the transaction of chain1 and I have DB_state_1 in the database.</p>

<p>How can I force the transaction of chain1 to complete before the message is sent to the <code>output-channel</code> of chain1?</p>

<p>I know I can use a <code>TransactionSynchronization</code> that sends the message to channel2 in <code>afterCommit()</code> but I assume there must be a more elegant solution.</p>

<p><code>EDIT CURRENT WORKAROUND</code></p>

<pre><code>@ServiceActivator
public void sendToDestinationFlow(Message&lt;?&gt; message) {
    TxSenderSyncer s = new TxSenderSyncer(message, this.channel, this.errorChannel);
    TransactionSynchronizationManager.registerSynchronization(s);
}

private static class TxSenderSyncer implements TransactionSynchronization {

    private Message&lt;?&gt; message;
    private MessageChannel channel;
    private MessageChannel errorChannel;

    public TxSenderSyncer(Message&lt;?&gt; message, MessageChannel channel, MessageChannel errorChannel) {
        this.message = message;
        this.channel = channel;
        this.errorChannel = errorChannel;
    }

    @Override
    public void afterCompletion(int paramInt) {
        if (paramInt == STATUS_ROLLED_BACK) {
            errorChannel.send(MessageBuilder.withPayload(new MessagingException(message, "Transaction rolled back")).build());
        } else {
            channel.send(message);
        }
    }
 }
</code></pre>