JMS can work with the Java Transaction API (JTA) to provide transaction management for messaging. When a transaction manager creates a transaction, resources such as JMS destinations can be enlisted with the transaction. When the application is done processing the data within the transaction, it can ask the transaction manager to commit the transaction. When this occurs, the transaction manager asks each of the resources if it can commit the changes made. If all resources claim they can commit the changes, the transaction manager asks all resources to commit their changes. If a resource claims it cannot commit its changes, the transaction manager directs the resources to undo any changes made. The application can also set the transaction to rollback only mode, which forces the transaction manager to roll back the transaction.

Note that message redelivery works only for SQL JMS destinations. For each JMS input destination, Patch Bay creates a thread that continuously loops through a cycle of beginning a transaction, receiving a message from the destination, and calling the configured message sink, and ending the transaction. If Patch Bay attempts to deliver a message to a message sink and an error condition arises (such as violation of a database constraint), the transaction is rolled back. The message remains in the destination, as if it were never delivered. Patch Bay tries to redeliver the message.

If the failed delivery is the result of some temporary condition, Patch Bay successfully delivers the message in a subsequent attempt. However, in some cases, the exception is caused by a problem with the message itself. This can result in an infinite loop, where the message delivery fails and the transaction is rolled back, and then Patch Bay continually tries to redeliver the message, and each time the delivery fails and the transaction is rolled back.

To avoid this situation, you can configure a message sink (or filter) so that only a certain number of attempts can be made to deliver a message to it. For example:

<message-sink>
  <nucleus-name>/fulfillment/OrderFulfiller</nucleus-name>
  <input-port>
    <input-destination>
      <destination-name>patchbay:/Fulfillment/SubmitOrder</destination-name>
      <destination-type>Topic</destination-type>
      <durable-subscriber-name>
        OrderFulfiller-SubmitOrder
      </durable-subscriber-name>
      <redelivery>
       <max-attempts>3</max-attempts>
       <delay>60000</delay>
       <failure-output-port>FulfillmentError</failure-output-port>
      </redelivery>
    </input-destination>
  </input-port>
  <redelivery-port>
    <port-name>FulfillmentError</port-name>
    <output-destination>
      <destination-name>patchbay:/Fulfillment/ErrorNotification</destination-name>
      <destination-type>Queue</destination-type>
    </output-destination>
  </redelivery-port>
</message-sink>

In this example, the message sink is configured so that Patch Bay makes a maximum of 3 attempts to deliver a message to it. The delay between each attempt is set to 60,000 milliseconds (10 minutes), which allows time for any transient errors responsible for a failed delivery to resolve themselves. This example also configures a destination to direct the message to if the delivery fails 3 times.

The redelivery port can define multiple destinations. The following example defines a second destination that has no components listening to it to act as a Dead Message queue. This allows the message to be kept in a JMS delivery engine waiting for eventual future delivery. After the source for the error is resolved, an administrator can use tools provided by the JMS provider to move the message back to the correct destination so that the message can be properly processed.

<redelivery-port>
  <port-name>FulfillmentError</port-name>
  <output-destination>
    <destination-name>patchbay:/Fulfillment/ErrorNotification</destination-name>
    <destination-type>Queue</destination-type>
  </output-destination>
  <output-destination>
    <destination-name>patchbay:/Fulfillment/DeadMessageQueue</destination-name>
    <destination-type>Queue</destination-type>
  </output-destination>
</redelivery-port>
Failed Message Redelivery and the MessageLimbo Service

The failed message redelivery system uses the MessageLimbo service discussed in the section Delaying the Delivery of Messages. There are thus two different types of messages handled by the MessageLimbo service:

  • Delayed messages that are not yet published to a JMS destination

  • Messages that were published to a destination, but were not successfully delivered to a message sink

These two types of messages are stored in the same set of tables, except that messages stored for redelivery have entries in one additional table named dms_limbo_delay. See Appendix B, DAF Database Schema for more information about these tables.

The maximum number of attempts to redeliver a failed message is set in the Patch Bay configuration file, using the max-attempts tag, as shown above. After this number of attempts, if the message still has not been successfully delivered to a message sink, Patch Bay creates a new message object and copies the message properties and message body into the new message. Patch Bay then attempts to publish the new message to the failure destination configured in the redelivery port.

If, due to some error condition, the new message cannot be published to the failure destination, the MessageLimbo service makes further attempts to publish the message. The maximum number of attempts is set by the limboDeliveryRetry property of the MessagingManager component. The default value of this property is 5, so after 5 attempts to publish the message, no further attempts are made, and the message remains in the database tables used by MessageLimbo. If the error condition is subsequently resolved, a database administrator can issue SQL statement to reset the counter on the message so the message is published. For example, the following SQL statement resets the counter for all messages being handled by the MessageLimbo service:

UPDATE dms_limbo_msg SET delivery_count=1

Copyright © 1997, 2013 Oracle and/or its affiliates. All rights reserved. Legal Notices