Class TransactionalOutbox

java.lang.Object
ch.admin.bit.jeap.messaging.transactionaloutbox.outbox.TransactionalOutbox

public class TransactionalOutbox extends Object
The transactional outbox allows to modify persistent data and send messages within one transaction. It does so by persisting the messages together with the data in the same database and within the same database transaction. The persisted messages are only sent after the transaction committed. If the transaction is rolled back, the messages won't be sent.

This outbox implementation supports two different ways for effectively sending the messages: send them immediately after the transaction committed in the transaction's thread or send them in a separate relay process that is scheduled to run periodically and poll the database for persisted messages to be sent. If there occurs a problem during the immediate sending of messages after the transaction committed, the immediate sending will be aborted and the messages will instead be sent later (after a certain delay) by the separate scheduled relay process (aka the second way).

For most use cases 'sending immediately' should be the appropriate way to send messages using the transactional outbox.

Sending immediately (send() methods) minimizes the latency and allows scaling up the sending of messages by scaling up the number of application instances. Sending scheduled (sendScheduled() methods) uses slightly less time in the thread that puts the messages in the outbox because the sending is done by another thread in the background or even by another application instance. On the downside sending scheduled in the background adds latency and is serial, i.e. there is no scaling up the effective sending by scaling up the number of application instances. However, if one application instance dies another one will pick up the sending in the background from the died instance.

Sending scheduled in the background can be disabled by setting jeap.messaging.transactional-outbox.scheduled-relay-enabled to false. This could be used to free application instances that are serving customer request from effectively sending messages and instantiate separate message relay service instances for effectively sending the messages.

  • Constructor Details

  • Method Details

    • sendMessage

      @Transactional(propagation=MANDATORY) public void sendMessage(ch.admin.bit.jeap.messaging.model.Message message, String topic)
      Send the given message to the given topic. Sending will happen immediately after the surrounding transaction got committed. If the immediate sending fails the message will be picked up again by the scheduled message relay process which will send it later after some delay.
      Parameters:
      message - The message
      topic - The topic
    • sendMessageScheduled

      @Transactional(propagation=MANDATORY) public void sendMessageScheduled(ch.admin.bit.jeap.messaging.model.Message message, String topic)
      Send the given message to the given topic. Sending will happen some time later when the scheduled message relay process will pick the message up and send it.
      Parameters:
      message - The message
      topic - The topic
    • sendMessage

      @Transactional(propagation=MANDATORY) public void sendMessage(ch.admin.bit.jeap.messaging.model.Message message, Object key, String topic)
      Send the given message with the given key to the given topic. Sending will happen immediately after the surrounding transaction got committed. If the immediate sending fails the message will be picked up again by the scheduled message relay process which will send it later after some delay.
      Parameters:
      message - The message
      key - The key
      topic - The topic
    • sendMessageScheduled

      @Transactional(propagation=MANDATORY) public void sendMessageScheduled(ch.admin.bit.jeap.messaging.model.Message message, Object key, String topic)
      Send the given message with the given key to the given topic. Sending will happen some time later when the scheduled message relay process will pick the message up and send it.
      Parameters:
      message - The message
      key - The key
      topic - The topic
    • countFailedMessages

      public int countFailedMessages(boolean resend)
      Count the number of messages having state 'failed'.
      Parameters:
      resend - Count only messages that have been marked for a resend (true) or not (false).
      Returns:
      The number of messages counted.
    • countFailedMessages

      public int countFailedMessages(ZonedDateTime failedStartingFrom, ZonedDateTime failedBefore, boolean resend)
      Count the number of messages having state 'failed' that failed during the specified interval.
      Parameters:
      failedStartingFrom - Only messages which have state 'failed' and failed starting from the given instant will be found.
      failedBefore - Count only messages which have state 'failed' and failed before the given instant will be found.
      resend - Only messages that have been marked for a resend (true) or not (false).
      Returns:
      The number of messages counted.
    • findFailedMessages

      public List<FailedMessage> findFailedMessages(ZonedDateTime failedStartingFrom, ZonedDateTime failedBefore, boolean resend, int maxNumMessagesToFind)
      Find messages that have state 'failed' and have an id greater than the given id and have failed before the given instant.
      Parameters:
      failedStartingFrom - Only messages which have state 'failed' and failed starting from the given instant will be found.
      failedBefore - Only messages which have state 'failed' and failed before the given instant will be found.
      resend - Find only messages that have been marked for a resend (true) or not (false).
      maxNumMessagesToFind - The maximum number of failed messages that will be found.
      Returns:
      The failed messages found ordered by their ids (ascending).
    • findFailedMessages

      public List<FailedMessage> findFailedMessages(long afterId, ZonedDateTime failedBefore, boolean resend, int maxNumMessagesToFind)
      Find messages that have state 'failed' and have an id greater than the given id and have failed before the given instant.
      Parameters:
      afterId - Only messages which have state 'failed' and Ids greater than the given id will be found.
      failedBefore - Only messages which have state 'failed' and failed before the given instant will be found.
      resend - Find only messages that have been marked for a resend (true) or not (false).
      maxNumMessagesToFind - The maximum number of failed messages that will be found.
      Returns:
      The failed messages found ordered by their ids (ascending).
    • resendMessageScheduled

      public void resendMessageScheduled(long id)
      Make the given outbox message available again to the message relay process for delivery.
      Parameters:
      id - The id of the outbox message to make available again to the message relay process for delivery.
      Throws:
      TransactionalOutboxException - if the message could not be found.