[[ConfluenceContent]]
[[SJMSBatch-SJMSBatchComponent]]
SJMS Batch Component
~~~~~~~~~~~~~~~~~~~~

*Available as of Camel 2.16*

SJMS Batch is a specialized component for highly performant,
transactional batch consumption from a JMS queue. It can be thought of
as a hybrid of a consumer-only component and an
link:aggregator2.html[aggregator].

A common use case in Camel is to consume messages from a queue and
aggregate them before sending the aggregated state to another endpoint.
In order to ensure that data is not lost if the system performing the
processing fails, it is typically consumed within a transaction from the
queue, and once aggregated stored in a persistent
`AggregationRepository`, such as the one found in the
link:jdbc.html[JDBC Component].

The behavior of the aggregator pattern involves fetching data from the
`AggregationRepository` before an incoming message is aggregated, and
writing back the result afterwards. By nature, the reads and writes take
progressively longer as the number of aggregated artifacts increases. A
rough example of this using arbitrary time units that demonstrates the
impact of this is as follows:

[cols=",,,",options="header",]
|=======================================
|Item |Read Time |Write Time |Total Time
|0 |0 |1 |1
|1 |1 |2 |4
|2 |2 |3 |9
|3 |3 |4 |16
|4 |4 |5 |25
|5 |5 |6 |36
|6 |6 |7 |49
|7 |7 |8 |64
|8 |8 |9 |81
|9 |9 |10 |100
|=======================================

In contrast, consumption performance using the SJMS Batch component is
linear. Each message is consumed and aggregated using an
`AggregationStrategy` before the next one is fetched. As all of the
consumption and aggregation is performed in a single JMS transaction no
external storage is required to persist the intermediate state - this
avoids the read and write costs described above. In practice, this
yields multiple orders of magnitude higher throughput.

Once a completion condition is met, either by size or period since first
message, the aggregated `Exchange` is passed into the route. During the
processing of this `Exchange`, if an exception is thrown or the system
shuts down, all of the original consumed messages end up back on the
queue (or are placed on the dead-letter queue depending on the broker
configuration).

Unlike using a regular aggregator, there is no facility for an
aggregation condition, meaning that it is not possible to batch consume
into multiple groups of messages. All consumed messages are aggregated
together into a single batch.

Multiple JMS consumer support is available which allows you to consume
in parallel using the one route, and at the same time use facilities
like JMS message groups to group related messages.

Maven users will need to add the following dependency to their `pom.xml`
for this component:

[source,xml]
----
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-sjms</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
----

[[SJMSBatch-URIformat]]
URI format
++++++++++

[source]
----
sjms:[queue:]destinationName[?options]
----

Where `destinationName` is a JMS queue. By default, the
`destinationName` is interpreted as a queue name.

[source]
----
sjms:FOO.BAR
----

You can include the optional `queue:` prefix, if you prefer:

[source]
----
sjms:queue:FOO.BAR
----

Topic consumption is not supported, as there is no advantage to using
batch consumption within that context. Topic messages are usually
non-persistent, and loss is acceptable. If consumed within a transaction
that fails, a topic message will likely not be redelivered by the
broker. A plain link:sjms.html[SJMS] consumer endpoint can be used in
conjunction with a regular non-persistence backed
link:aggregator2.html[aggregator] in this scenario.

[[SJMSBatch-ComponentOptionsandConfigurations]]
Component Options and Configurations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The SJMS Batch Component supports the following configuration options:

[width="100%",cols="10%,10%,10%,80%",options="header",]
|=======================================================================
|Option |Required |Default Value |Description
|`aggregationStrategy`
| icon:check[]
|`null` |A reference to an `AggregationStrategy` in the Camel registry
(e.g. `#myAggregationStrategy`)

|`completionSize` |  |`200` a|
The size of the batch to aggregate.

Care should be taken to ensure that this is not larger than the JMS
consumer's prefetch buffer, or the maximum page size for a queue on the
broker; either of these could cause the consumer to hang if no timeout
is used.

A value of 0 or less indicates that `completionTimeout` only should be
used.

|`completionTimeout` |  |`500` a|
The maximum time to wait from the receipt of the first message before
emitting the Exchange.

A value of 0 or less indicates that `completionSize` only should be
used.

|`pollDuration` |  |`1000` a|
The maximum length of a call to `MessageConsumer.receive()`. The time
remaining before timeout takes precedence within a batch.

This value is effectively the poll time between batches.

|=======================================================================

The `completionSize` endpoint attribute is used in conjunction with
`completionTimeout`, where the first condition to be met will cause the
aggregated `Exchange` to be emitted down the route.
