@Idempotent(
key = "#event.id()", // SpEL over the method's parameters. Required here
scope = "", // Empty: <simple class name>.<method name>
ttl = "PT24H", // How long the record stays replayable (ISO-8601)
lease = "PT30S", // How long this acquisition is protected
waitTimeout = "PT10S", // How long a concurrent caller blocks. "PT0S" to not block
completion = "", // autonomous | join-transaction
codec = "" // PayloadCodec bean name, for a method that returns a value
)Attributes
| Attribute | Default when empty | Notes |
|---|---|---|
key |
- | SpEL over the method’s parameters. Required on a method; rejected on an endpoint |
scope |
<simple class name>.<method name> |
See scope and key |
ttl |
idempotency.default-ttl |
ISO-8601 duration |
lease |
idempotency.default-lease |
ISO-8601 duration |
waitTimeout |
idempotency.default-wait |
ISO-8601 duration. PT0S to not block |
completion |
idempotency.completion-mode |
autonomous or join-transaction. Rejected on an endpoint |
codec |
- | PayloadCodec bean name. Required on a value-returning method, rejected on a void one and on an endpoint |
Every attribute except key, scope and codec takes the application default from
configuration when left empty.
Rejected on an endpoint, and why
Three attributes are rejected at startup on a request mapping handler:
| Attribute | Why |
|---|---|
key |
An HTTP request brings its own key in the header. A second key from the annotation would mean two identities for one call |
codec |
The filter stores the HTTP response through its own StoredResponseCodec |
completion |
The filter completes after the response is captured, outside any method transaction |
Validation
Anything malformed - an unparseable duration, an unknown completion mode, an over-long scope,
a value-returning method with no codec, a void method with one - is rejected when the
context starts, not on the first message.
Behaviour on a void method
There is nothing to replay, so codec must be empty. A duplicate returns without running the
method. The outcome still distinguishes Executed from
Replayed for a lifecycle listener that cares.