Very slow performance when switching from local JMS transactions to XA transaction in Camel using Aries Transaction Manager

Solution Verified - Updated -

Environment

  • Fuse ESB 4.4.x

Issue

This article applies to versions of ServiceMix up to 4.4.1-fuse-07-11.

After turning on XA transactions in my Camel route (leveraging the Aries transaction manager), the performance degrades drastically. In the best case I am only able to process 16 msgs/sec in my Camel consumer.
While using local JMS transactions performance is at least 10x higher.

Resolution

With the fix of ESB-1733 future versions of the Aries Transaction Manager will have this flag set to true by default and will also expose this configuration externally.

So if you want to change this setting, you can do so in $SMX_HOME/etc/org.apache.aries.transaction.cfg by setting

aries.transaction.flushPartialBuffers=false;

which will degrade performance in case of low concurrency use of the transaction manager (i.e. only a small number of concurrent clients doing XA transactions).

Root Cause

The Geronimo transaction log writer (Howl) has an optimization configuration called flushPartialBuffers that is particularly useful in low concurrency scenarios.
This variable indicates whether LogBufferManager should flush buffers before they are full and default to false.

From the Java source itself:

/**
   * Indicates whether LogBufferManager should flush buffers
   * before they are full.
   * 
   * <p>Normally, buffers are flushed to disk only when
   * they become full.  In lightly loaded situations,
   * one or more threads may have to wait until the
   * flushSleepTime expires before the buffer is written.
   * In the worst case, a single thread is using the
   * log, and every put() with sync requested will
   * be delayed flushSleepTime ms before the buffer is
   * written.
   * 
   * <p>Setting flushPartialBuffers true will allow
   * the LogBufferManager to flush buffers to disk
   * any time the channel is not busy.  This improves
   * throughput in single threaded and lightly loaded
   * environments. 
   * 
   * <p>By default, this feature is disabled (false) to
   * provide compatability with earlier versions of
   * this library.
   */
  private boolean flushPartialBuffers = false;

Versions of ServiceMix up to 4.4.1-fuse-07-11 have this variable set to false and it is not exposed to be configured externally.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.