Interface TransactionManager

All Known Subinterfaces:
JdbcTransactionManager
All Known Implementing Classes:
DataSourceTransactionManager, JsonTransactionManager

public interface TransactionManager
Interface for managing database transactions.

Implementations handle transaction boundaries (begin, commit, rollback) and provide connections that are aware of the current transaction context.

JDBC-specific members -- getConnection(), setIsolationLevel(int) and setReadOnly(boolean) -- live on JdbcTransactionManager; their deprecated defaults on this interface were removed in 6.4.0.

Since:
6.2.0
Author:
wisdomme
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Begins a new transaction.
    void
    Commits the current transaction.
    default Long
    Returns the System.nanoTime() value at which the active transaction's timeout budget expires, or null when no timeout is configured for the active transaction -- no active transaction at all, or @Transactional(timeout=0) (the default).
    int
    Gets the current transaction depth (for nested transactions).
    boolean
    Checks if there is an active transaction on the current thread.
    default void
    resume(Object suspended)
    Restores a transaction previously detached by suspend().
    void
    Rolls back the current transaction.
    void
    setTimeout(int seconds)
    Sets the timeout for the current transaction.
    default Object
    Suspends the current transaction, if any, detaching it from this thread so an independent transaction can begin in its place.
  • Method Details

    • begin

      void begin()
      Begins a new transaction.

      Creates a new connection, disables auto-commit, and associates it with the current thread.

      Throws:
      DataAccessException - if transaction cannot be started
    • commit

      void commit()
      Commits the current transaction.

      Commits all changes made during the transaction and releases the connection.

      What a failed commit means depends on the implementation:

      • For the JDBC implementation used by SQLite and MySQL (DataSourceTransactionManager), a DataAccessException (TRANSACTION_FAILED) raised because Connection.commit() failed leaves the outcome unknown: the database may have applied the commit before the failure reached the framework.
      • For the JSON implementation (JsonTransactionManager), a failed commit commits nothing, as its commit() javadoc states.
      • On every implementation, an UnexpectedRollbackException means the transaction had been marked rollback-only and was rolled back: none of its writes was stored.
      Implementations do not retry the commit. A caller that must not apply a write twice re-reads the data, or makes the write conditional (DataOperator#updateIf), before trying again after an unknown outcome.
      Throws:
      DataAccessException - if commit fails; on SQLite and MySQL, when Connection.commit() failed, whether the database stored the transaction is unknown
      UnexpectedRollbackException - if the transaction had been marked rollback-only; it was rolled back instead of committed
    • rollback

      void rollback()
      Rolls back the current transaction.

      Discards all changes made during the transaction and releases the connection.

    • hasActiveTransaction

      boolean hasActiveTransaction()
      Checks if there is an active transaction on the current thread.
      Returns:
      true if a transaction is active
    • setTimeout

      void setTimeout(int seconds)
      Sets the timeout for the current transaction.

      Note: Not all databases/drivers support transaction timeout.

      Parameters:
      seconds - the timeout in seconds
    • getTimeoutDeadlineNanos

      default Long getTimeoutDeadlineNanos()
      Returns the System.nanoTime() value at which the active transaction's timeout budget expires, or null when no timeout is configured for the active transaction -- no active transaction at all, or @Transactional(timeout=0) (the default).

      D-10: consulted per statement (by TimeoutAwareQueryRunner and the two direct PreparedStatement call sites AbstractRelationalDataOperator.insertAll/ updateAll build themselves) to compute the time remaining in the budget, not a value captured once -- the caller re-reads this on every statement.

      The default implementation always returns null, meaning "never enforced" -- the same posture a backend whose setTimeout(int) refuses any positive value outright (rather than ever recording a deadline) naturally has, since it never has anything to report here either. A backend that wants per-statement enforcement overrides this together with setTimeout(int) -- overriding only one half of the pair leaves the other silently inert, the same caution suspend()'s javadoc gives for its pair.

      Returns:
      the deadline, as a System.nanoTime() value, or null if none is active
      Since:
      6.3.0
    • getTransactionDepth

      int getTransactionDepth()
      Gets the current transaction depth (for nested transactions).
      Returns:
      the transaction depth (0 if no transaction)
    • suspend

      default Object suspend()
      Suspends the current transaction, if any, detaching it from this thread so an independent transaction can begin in its place. Backs Propagation.REQUIRES_NEW and Propagation.NOT_SUPPORTED (D-09).

      Deliberately typed to return an opaque Object rather than a backend-specific context type: a JDBC-backed manager suspends a Connection-holding context, the JSON manager suspends the transaction's context, which carries its staged writes and its table lock holds - neither shape belongs on this base interface. Pass whatever this returns to resume(Object) to restore it; the caller must not otherwise inspect or reuse the returned value.

      The default implementation does not support suspension: it always returns null, meaning nothing was suspended. A backend that maintains thread-bound transaction state (JDBC, JSON) must override this together with resume(Object) - overriding only one of the pair breaks the contract silently.

      Returns:
      an opaque handle to resume later, or null if no transaction was active
      Since:
      6.3.0
    • resume

      default void resume(Object suspended)
      Restores a transaction previously detached by suspend().

      null is a no-op - it means suspend() found nothing active in the first place, so there is nothing to restore. Passing a handle this TransactionManager did not itself produce is a programming error.

      The default implementation is a no-op, pairing with suspend()'s default of always returning null.

      Parameters:
      suspended - the handle returned by a prior suspend() call, or null
      Since:
      6.3.0