Skip to content

Transaction Semantics

This page defines transaction propagation, physical completion, transaction attributes, and failure handling.

❗️Transaction types
Type Active transaction No active transaction
REQUIRED Join it Start one
REQUIRES_NEW Suspend it and start one Start one
MANDATORY Join it Fail before invocation
SUPPORTS Join it Run without a transaction
NOT_SUPPORTED Suspend it and run without a transaction Run without a transaction
NEVER Fail before invocation Run without a transaction

Only the scope that started a transaction completes it automatically. A joined scope uses the same connection and may mark the shared transaction rollbackOnly.

REQUIRES_NEW completes independently of the suspended transaction. Suspended contexts are restored after success, failure, or error. An inner failure affects a suspended transaction only when it propagates into that transaction.

Any participating scope may request an explicit intermediate completion with commitAndContinue().

❗️Transaction completion

A new transaction acquires one fresh provider connection. The connection must initially have auto-commit enabled; otherwise the manager closes it and throws KaumeiTxException.

The manager disables auto-commit and applies concrete isolation and read-only requirements before invoking the callback.

Callback outcome Owning scope Joined scope
Normal return Commit unless rollbackOnly Leave completion to the owner
Failure requiring rollback Roll back and preserve the failure Mark rollbackOnly and preserve the failure
Failure not requiring rollback Commit and preserve the failure Preserve the failure without changing rollbackOnly

A rollbackOnly transaction rolls back and reports an unchecked transaction failure. A commit failure triggers a best-effort rollback and produces completion status UNKNOWN. A rollback failure also produces UNKNOWN. A failed commit remains UNKNOWN even when the best-effort rollback succeeds.

Final completion restores every changed isolation and read-only value and restores auto-commit to enabled. It then closes the connection and restores any suspended context. The manager never intentionally closes a connection with an active physical transaction.

Registered synchronisations participate in each completion attempt as defined by the Transaction API.

❗️Intermediate commit

commitAndContinue() completes the current physical transaction while retaining its transaction context and connection. It requires an active context in state RUNNING and may be called by any participating scope.

It does not execute or inspect pending JDBC batches. Isolation, read-only, and auto-commit state remain unchanged. Open statements and empty batch objects may be reused only when supported by the JDBC driver. The next JDBC operation starts the next physical transaction.

The final owning-scope completion affects only the last physical transaction. Already committed work cannot be rolled back by a later failure.

Completion State transition
Successful intermediate commit RUNNINGCOMPLETINGRUNNING
Final completion RUNNINGCOMPLETINGFINISHED
Failed intermediate completion RUNNINGCOMPLETINGFINISHED

An intermediate attempt uses normal synchronisation and physical-completion rules but does not restore connection state or close the connection. Its registered synchronisations are removed after the attempt and must be registered again for a later physical transaction.

When an intermediate completion fails:

  • normal best-effort rollback and completion-status rules apply;
  • the first completion failure becomes the terminal transaction failure;
  • commitAndContinue() throws that failure immediately;
  • the context rejects further transaction work;
  • final owning-scope completion performs only restoration and close;
  • the terminal failure remains primary even when the callback catches it;
  • later callback and cleanup failures are suppressed on that failure.
❗️Transaction attributes

KaumeiTxDefinition supports these transaction attributes:

Attribute Values Default
Isolation READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE DEFAULT
Read-only READ_ONLY, READ_WRITE DEFAULT

For a new transaction, DEFAULT does not call the corresponding JDBC setter. A concrete value is applied before the callback. The original value is restored after final completion.

A failure while applying an attribute aborts transaction start and closes the acquired connection. A restoration failure follows the normal primary and suppressed failure rules.

For a joined transaction, DEFAULT is always compatible and never changes connection state. A concrete value is compatible only when the active transaction was started with the same concrete requirement. If the active transaction was started with DEFAULT, a joined scope may require only DEFAULT for that attribute. An incompatible requirement throws IllegalStateException before callback invocation.

❗️Rollback rules
Failure Default outcome
RuntimeException Roll back
Error Roll back
Checked exception Commit

Rollback matching uses this order:

  1. Error always requires rollback and cannot be overridden by dontRollbackOn.
  2. A matching dontRollbackOn prevents rollback.
  3. A matching rollbackOn requires rollback.
  4. Any other RuntimeException requires rollback.
  5. Any other Throwable does not require rollback.

Matchers receive the thrown Throwable directly. The manager performs no class, method, or annotation inspection. If a matcher throws, the transaction is marked for rollback. The callback failure remains primary and the matcher failure is attached as a suppressed exception.

The first operation or transaction failure remains primary. Rollback, callback, state-restoration, and close failures are attached as suppressed exceptions. Without an earlier failure, the first completion or cleanup failure is primary.

Transaction-manager failures are unchecked KaumeiTxException instances. Checked callback failures retain their identity.