Interface TransactionOutbox.ParameterizedScheduleBuilder
- Enclosing interface:
TransactionOutbox
-
Method Summary
Modifier and TypeMethodDescriptiondelayForAtLeast
(Duration duration) Instructs the scheduler to delay processing the task until after the specified duration.Specifies that the request should be applied in a strictly-ordered fashion within the specified topic.<T> T
Equivalent toTransactionOutbox.schedule(Class)
, but applying additional parameters to the request as configured usingTransactionOutbox.with()
.uniqueRequestId
(String uniqueRequestId) Specifies a unique id for the request.
-
Method Details
-
uniqueRequestId
Specifies a unique id for the request. This defaults tonull
, but if non-null, will cause the request to be retained in the database after completion for the specifiedTransactionOutbox.TransactionOutboxBuilder.retentionThreshold(Duration)
, during which time any duplicate requests to schedule the same request id will throwAlreadyScheduledException
. This allows tasks to be scheduled idempotently even if the request itself is not idempotent (e.g. from a message queue listener, which can usually only work reliably on an "at least once" basis).- Parameters:
uniqueRequestId
- The unique request id. May benull
, but if non-null may be a maximum of 250 characters in length. It is advised that if these ids are client-supplied, they be prepended with some sort of context identifier to ensure global uniqueness.- Returns:
- Builder.
-
ordered
Specifies that the request should be applied in a strictly-ordered fashion within the specified topic.This is useful for a number of applications, such as feeding messages into an ordered pipeline such as a FIFO queue or Kafka topic, or for reliable data replication, such as when feeding a data warehouse or distributed cache.
Note that using this option has a number of consequences:
- Requests are not processed immediately when submitting a request, as normal, and are
processed by
TransactionOutbox.flush()
only. As a result there will be increased delay between the source transaction being committed and the request being processed. - If a request fails, no further requests will be processed in that topic until
a subsequent retry allows the failing request to succeed, to preserve ordered
processing. This means it is possible for topics to become entirely frozen in the event
that a request fails repeatedly. For this reason, it is essential to use a
TransactionOutboxListener
to watch for failing requests and investigate quickly. Note that other topics will be unaffected. - For the same reason,
TransactionOutbox.TransactionOutboxBuilder.blockAfterAttempts
is ignored for all requests that use this option. The only safe way to recover from a failing request is to make the request succeed. - A single topic can only be processed in single-threaded fashion, so if your requests use a small number of topics, scalability will be affected since the degree of parallelism will be reduced.
- Throughput is significantly reduced and database load increased more generally, even with larger numbers of topics, since records are only processed one-at-a-time rather than in batches, which is less optimised.
- In general, databases are not well optimised for this sort of thing. Don't expect miracles. If you need more throughput, you probably need to think twice about your architecture. Consider the event sourcing pattern, for example, where the message queue is the primary data store rather than a secondary, and remove the need for an outbox entirely.
- Parameters:
topic
- a free-text string up to 250 characters.- Returns:
- Builder.
- Requests are not processed immediately when submitting a request, as normal, and are
processed by
-
delayForAtLeast
Instructs the scheduler to delay processing the task until after the specified duration. This can be used for simple job scheduling or to introduce an asynchronous delay into chains of tasks.Note that any delay is not precise and accuracy is primarily determined by the frequency at which
TransactionOutbox.flush(Executor)
orTransactionOutbox.flush()
are called. Do not use this for time-sensitive tasks, particularly if the duration exceedsTransactionOutbox.TransactionOutboxBuilder.attemptFrequency(Duration)
(see more on this below).A note on implementation: tasks (when
ordered(String)
is not used) are normally submitted for processing on the local JVM immediately after transaction commit. By default, when a delay is introduced, the work is instead submitted to aScheduledExecutorService
for processing after the specified delay. However, if the delay is long enough that the work would likely get picked up by aTransactionOutbox.flush()
on this JVM or another, this is pointless and wasteful. Unfortunately, we don't know exactly how frequentlyTransactionOutbox.flush()
will be called! To mitigate this, Any task submitted with a delay in excess ofTransactionOutbox.TransactionOutboxBuilder.attemptFrequency(Duration)
will be assumed to get picked up by a future flush.- Parameters:
duration
- The minimum delay duration.- Returns:
- Builder.
-
schedule
Equivalent toTransactionOutbox.schedule(Class)
, but applying additional parameters to the request as configured usingTransactionOutbox.with()
.Usage example:
transactionOutbox.with() .uniqueRequestId("my-request") .schedule(MyService.class) .runMyMethod("with", "some", "arguments");
- Type Parameters:
T
- The type to proxy.- Parameters:
clazz
- The class to proxy.- Returns:
- The proxy of
T
.
-