Skip to content

Declarative Transactions

@KaumeiTx declares transaction requirements for a type or method. The annotation has no effect by itself. It requires KaumeiTxProxy or a framework integration that maps it to KaumeiTxManager.

❗️Annotation mapping

@KaumeiTx is declared in io.kaumei.jdbc.annotation. It is documented, inherited, retained at runtime, and valid on types and methods.

Attribute Values Default
value REQUIRED, REQUIRES_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NEVER MANDATORY
isolation DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE DEFAULT
readOnly DEFAULT, READ_ONLY, READ_WRITE DEFAULT
rollbackOn Classes extending Throwable Empty
dontRollbackOn Classes extending Throwable Empty

Annotation transaction types map directly to the corresponding KaumeiTxManager method. Isolation and read-only values map to the corresponding KaumeiTxDefinition values. Exception matching includes subclasses of every configured exception class.

Completion, attributes, and rollback behaviour are defined by Transaction Semantics.

A bare @KaumeiTx means MANDATORY. The annotated method must join a transaction owned by its caller and does not create a new transaction boundary.

A method that intentionally owns a transaction boundary must declare REQUIRED or REQUIRES_NEW explicitly. A method that intentionally permits execution without an active transaction must declare SUPPORTS, NOT_SUPPORTED, or NEVER, or have no resolved annotation.

The MANDATORY default prevents repository calls from silently creating independent transactions and committing partial business operations.

❗️Runtime interface proxy

KaumeiTxProxy.wrap(api, target, txManager) creates the framework-independent runtime integration for an annotated interface.

Construction requires all three arguments. api must be a public interface and target must implement it. The target must obtain JDBC connections through the same manager passed to the proxy. Null construction arguments cause NullPointerException. An invalid API or target causes IllegalArgumentException.

Annotation resolution and transaction definitions are prepared once when the proxy is created. Conflicting annotations at the same interface-hierarchy level cause IllegalArgumentException.

For each invoked interface method, the proxy resolves annotations in this order:

  1. Use the annotation on the nearest declaration of that interface method.
  2. An unannotated override stops lookup on overridden parent methods.
  3. If no method annotation resolves, use the nearest annotated interface.
  4. If no annotation resolves, invoke the target directly without a manager call.

Only interface and interface-method annotations participate. Annotations on the target class or its methods are ignored.

All six transaction types invoke the corresponding KaumeiTxManager method. Isolation, read-only, rollbackOn, and dontRollbackOn are converted to one prepared KaumeiTxDefinition.

Abstract and default interface methods are supported. void methods use the void callback overload. Value-returning methods use the nullable *Opt overload, so the proxy does not interpret or enforce the business method’s return contract.

Checked exceptions, runtime exceptions, and errors retain their identity. equals, hashCode, and toString use proxy identity and do not invoke the transaction manager.

Runtime annotation inspection and reflection are confined to the proxy. They are not part of the transaction-manager state machine. Stack-visible proxy frames describe business-method and transactional invocation. The exact stack-trace layout is not an API compatibility guarantee.

The JDBC annotation processor does not currently generate transaction calls for @KaumeiTx. Generated transaction handling is planned work and is not part of the current public specification. See the roadmap.

The transaction manager remains free of framework dependencies. An integration that requires an external framework dependency belongs in a separate project. Only framework-independent integration points belong in the core transaction API.

Framework aspects, generated proxies, annotation lookup, and their reflection strategies are not transaction-manager semantics. An integration that implements @KaumeiTx must delegate transaction handling to KaumeiTxManager and use that same manager as the JdbcConnectionProvider for participating generated JDBC implementations. When an external framework owns transaction boundaries, generated JDBC implementations instead use that framework’s transaction-aware connection provider and jdbc-tx is not involved.

The Avaje Inject integration is a non-normative example in which jdbc-tx owns transaction boundaries. Its aspect, annotation mapping, and reflection strategy do not define the transaction-manager contract. The Spring examples use Spring transaction managers and deliberately do not use jdbc-tx. See the integration overview for the available integrations and their transaction owners.