Class TransactionManager
Commit path — Raft-replicated atomic batch (v2.0):
On commit(UUID) buffered operations are bundled into a single
atomic, replicated batch
and submitted to the Raft group via BatchExecutionHandler. Once the batch is
committed to the Raft log, it is applied on every replica atomically by the state
machine. This ensures transactional mutations survive a coordinator crash after
commit is acknowledged.
When sharding is enabled and the transaction's keys span more than one Raft group,
the manager delegates to CrossGroupTransactionExecutor which coordinates a
Raft-serialized cross-group execution.
Local commit fallback is disabled by default because it is not replicated. Test-only
harnesses can opt in with -Dloomcache.transactions.allow-local-commit-fallback=true.
Features:
- Virtual thread-based timeout monitoring (no blocking of physical threads)
- Automatic rollback of timed-out transactions
- Transaction isolation and deadlock prevention via per-structure lock ordering
- Comprehensive statistics tracking (started, committed, rolled back, timed out)
Thread Safety: This class is thread-safe. Multiple threads can safely begin, commit, and rollback transactions concurrently.
- Since:
- 1.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordstatic final recordStatistics about transaction execution. -
Constructor Summary
ConstructorsConstructorDescriptionTransactionManager(DataStructureRegistry registry) Creates a new transaction manager with a local (non-replicated) commit path.TransactionManager(DataStructureRegistry registry, @Nullable BatchExecutionHandler batchHandler, @Nullable CrossGroupTransactionExecutor crossGroupExecutor, @Nullable PartitionRouter partitionRouter) Creates a new transaction manager with optional Raft-replicated commit. -
Method Summary
Modifier and TypeMethodDescriptionintabortActiveTransactionsDueToLeadershipLoss(@Nullable String newLeaderId) Best-effort abort of locally buffered transactions after this node loses leadership.beginReplicatedTransaction(UUID transactionId, long timeoutMillis, long startTimeMillis) Restores or applies a Raft-replicated coordinator transaction session.beginTransaction(long timeoutMillis) Begins a new transaction with the specified timeout.voidbufferReplicatedOperation(UUID transactionId, TransactionOp operation) Applies a buffered operation that was replicated through the coordinator log.voidCommits a transaction and cleans up internal state.voidcommitBufferedTransaction(UUID transactionId, long timeoutMillis, List<TransactionOp> operations) Commits a stateless wire transaction whose operations were buffered client-side.voidcommitBufferedTransaction(UUID transactionId, long timeoutMillis, List<TransactionOp> operations, @Nullable String replicatedSenderId) booleandiscardReplicatedTransaction(UUID transactionId, boolean failIfMissing) Drops replicated coordinator state without replaying a data rollback.static StringdurableCoordinatorCommitSenderId(UUID transactionId) Stable idempotency sender metadata for the replicated batch generated by a durable stateful coordinator commit.Gets all active transaction IDs.getStats()Gets statistics about transaction execution.@Nullable TransactionContextgetTransaction(UUID transactionId) Gets a transaction by ID.@Nullable StringlockKeyForUpdate(UUID transactionId, String mapName, String key) Replicated coordinator mutation forTransactionalMap.getForUpdate.voidrestoreRecoverableTransactions(@Nullable Object snapshotValue) Restores the Raft-replicated coordinator sessions from a state-machine snapshot.voidRolls back a transaction and cleans up internal state.voidsetShardedBatchHandlerResolver(@Nullable Function<Integer, BatchExecutionHandler> resolver) Installs an optional resolver that maps a single Raft group ID to theBatchExecutionHandlerbound to that group's registry slice.Snapshots the currently active Raft-replicated coordinator sessions.voidstart()Starts the timeout monitor thread as a virtual thread.voidstop()Stops the transaction manager and its timeout monitor.static TransactionManagerCreates a manager that may use the legacy in-memory commit path when an operation is not representable as a replicated batch.
-
Constructor Details
-
TransactionManager
Creates a new transaction manager with a local (non-replicated) commit path.This constructor is intended for unit tests that exercise the manager against an in-memory registry without a Raft node. Production wiring must use
TransactionManager(DataStructureRegistry, BatchExecutionHandler, CrossGroupTransactionExecutor, PartitionRouter).- Parameters:
registry- the data structure registry (must not be null)- Throws:
NullPointerException- if registry is null
-
TransactionManager
public TransactionManager(DataStructureRegistry registry, @Nullable BatchExecutionHandler batchHandler, @Nullable CrossGroupTransactionExecutor crossGroupExecutor, @Nullable PartitionRouter partitionRouter) Creates a new transaction manager with optional Raft-replicated commit.- Parameters:
registry- the data structure registry (must not be null)batchHandler- batch execution handler used to replicate atomic commits through Raft;nulldisables replication and falls back to local applycrossGroupExecutor- executor used when buffered operations span multiple Raft groups (sharding enabled);nulldisables cross-group routingpartitionRouter- partition router used to detect multi-group transactions;nullwhen sharding is disabled- Throws:
NullPointerException- if registry is null
-
-
Method Details
-
withLocalCommitFallbackForTests
Creates a manager that may use the legacy in-memory commit path when an operation is not representable as a replicated batch.This is intentionally named for tests so production wiring keeps using the fail-closed constructors unless an operator explicitly opts in via the local-fallback system property.
-
setShardedBatchHandlerResolver
public void setShardedBatchHandlerResolver(@Nullable Function<Integer, BatchExecutionHandler> resolver) Installs an optional resolver that maps a single Raft group ID to theBatchExecutionHandlerbound to that group's registry slice.When absent, replicated single-group commits continue to use the default
batchHandler. CacheNode wires this only in sharded mode. -
getKeyLockManager
-
start
public void start()Starts the timeout monitor thread as a virtual thread.The monitor runs periodically (every 100ms) to check for timed-out transactions and automatically rolls them back. Using a virtual thread avoids blocking physical threads.
-
stop
public void stop()Stops the transaction manager and its timeout monitor.Waits up to 5 seconds for the monitor thread to gracefully terminate. After stopping, no new transactions can be started.
-
beginTransaction
Begins a new transaction with the specified timeout.- Parameters:
timeoutMillis- the timeout in milliseconds (must be positive)- Returns:
- a new TransactionContext (never null)
- Throws:
IllegalArgumentException- if timeoutMillis invalid input: '<'= 0
-
beginReplicatedTransaction
public TransactionContext beginReplicatedTransaction(UUID transactionId, long timeoutMillis, long startTimeMillis) Restores or applies a Raft-replicated coordinator transaction session.Used by the legacy stateful transaction protocol, whose buffered pre-commit state now survives leader failover through Raft replication and state-machine snapshots.
-
bufferReplicatedOperation
Applies a buffered operation that was replicated through the coordinator log. -
lockKeyForUpdate
-
discardReplicatedTransaction
Drops replicated coordinator state without replaying a data rollback.Used both for replicated TX_ROLLBACK and for post-commit cleanup of the replicated coordinator session.
-
snapshotRecoverableTransactions
Snapshots the currently active Raft-replicated coordinator sessions. -
restoreRecoverableTransactions
Restores the Raft-replicated coordinator sessions from a state-machine snapshot. -
commitBufferedTransaction
public void commitBufferedTransaction(UUID transactionId, long timeoutMillis, List<TransactionOp> operations) Commits a stateless wire transaction whose operations were buffered client-side.This path avoids server-side session pinning: the client submits the full operation list at commit time, and the manager executes it through the same replicated commit logic used by stateful transactions.
- Parameters:
transactionId- client-visible transaction id for logging and error reportingtimeoutMillis- remaining transaction timeout in millisecondsoperations- buffered operations to commit atomically
-
commitBufferedTransaction
public void commitBufferedTransaction(UUID transactionId, long timeoutMillis, List<TransactionOp> operations, @Nullable String replicatedSenderId) -
commit
Commits a transaction and cleans up internal state.Chooses one of three commit paths:
- Cross-group Raft: when sharding is enabled and the transaction's
map-keys span more than one Raft group, the ops are translated into a
Transactionand submitted viaCrossGroupTransactionExecutor. - Replicated atomic batch: when
BatchExecutionHandleris wired and all buffered ops translate cleanly to batch opcodes, the whole batch is submitted to Raft and applied by the state machine on every node. - Local fallback: disabled by default; only explicit test harnesses or operator opt-in may apply an unreplicated in-memory commit.
- Parameters:
transactionId- the transaction ID (must not be null)- Throws:
IllegalArgumentException- if transaction not found
- Cross-group Raft: when sharding is enabled and the transaction's
map-keys span more than one Raft group, the ops are translated into a
-
durableCoordinatorCommitSenderId
Stable idempotency sender metadata for the replicated batch generated by a durable stateful coordinator commit.CacheNode uses the same key to deduplicate ambiguous external TX_COMMIT retries after the first replicated batch outcome has already been learned through state-machine apply.
-
rollback
Rolls back a transaction and cleans up internal state.- Parameters:
transactionId- the transaction ID (must not be null)- Throws:
IllegalArgumentException- if transaction not found
-
abortActiveTransactionsDueToLeadershipLoss
Best-effort abort of locally buffered transactions after this node loses leadership.Only transactions still in
TransactionContext.TransactionState.ACTIVEare aborted here. Transactions already COMMITTING may have submitted their replicated command, so their final outcome is governed by the regular commit path.- Parameters:
newLeaderId- identifier of the new leader, if known- Returns:
- number of transactions definitively rolled back on this node
-
getTransaction
Gets a transaction by ID.- Parameters:
transactionId- the transaction ID (must not be null)- Returns:
- the TransactionContext, or null if not found
-
getActiveTransactionIds
-
getStats
Gets statistics about transaction execution.- Returns:
- current transaction manager statistics (never null)
-