Class CrossGroupTransactionExecutor
java.lang.Object
com.loomcache.server.sharding.CrossGroupTransactionExecutor
Executes transactions atomically via Raft command serialization.
Protocol (Raft-serialized):
- Serialize the entire transaction (conditions + THEN/ELSE ops) as a single Raft command
- Submit via
CrossGroupTransactionExecutor.RaftTransactionSubmitter— the command is committed to the Raft log - On each node's state machine apply: evaluate conditions, execute THEN/ELSE ops atomically under the local transactionLock (protects map state during apply)
Raft log serialization provides mutual exclusion — no GroupLockManager needed. Both single-group and cross-group transactions use the same Raft-serialized path, eliminating the lock-domain mismatch where concurrent single-map and cross-group transactions could interleave on the same map.
Falls back to local lock-based execution when no Raft submitter is configured (single-node / test mode).
Per-operation map resolution (ESC-14)
The apply path resolves aDistributedMap for each (groupId, mapName)
pair touched by the transaction. The mapName comes either from the per-op
Transaction.Operation.mapName() override or from the group's single
recorded map (legacy single-map cross-group TX case). All resolved maps are
locked in (groupId asc, mapName asc) order before condition evaluation
to keep the apply atomic even when a single Raft group carries multiple maps.- Since:
- 2.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceSubmits a transaction through Raft consensus for linearizable execution. -
Constructor Summary
ConstructorsConstructorDescriptionCrossGroupTransactionExecutor(PartitionRouter router, GroupLockManager lockManager) Create a cross-group transaction executor (local lock-based fallback).CrossGroupTransactionExecutor(PartitionRouter router, GroupLockManager lockManager, @Nullable CrossGroupTransactionExecutor.RaftTransactionSubmitter raftSubmitter, Duration lockTimeout) Create a cross-group transaction executor with Raft-serialized transactions. -
Method Summary
Modifier and TypeMethodDescriptionapplyCommittedTransaction(ReplicatedTransactionCommand command, BiFunction<Integer, String, DistributedMap<String, String>> mapResolver) Apply a committed transaction using a per-op (groupId, mapName) → map resolver.applyCommittedTransaction(ReplicatedTransactionCommand command, Function<Integer, DistributedMap<String, String>> mapResolver) applyCommittedTransaction(Transaction transaction, Function<Integer, DistributedMap<String, String>> mapResolver) Apply a Raft-committed transaction locally.execute(ReplicatedTransactionCommand command, BiFunction<Integer, String, DistributedMap<String, String>> mapResolver) execute(ReplicatedTransactionCommand command, Function<Integer, DistributedMap<String, String>> mapResolver) execute(Transaction transaction, Function<Integer, DistributedMap<String, String>> mapResolver) Execute a cross-group transaction.
-
Constructor Details
-
CrossGroupTransactionExecutor
Create a cross-group transaction executor (local lock-based fallback).- Parameters:
router- the partition router for key-to-group mappinglockManager- the group lock manager
-
CrossGroupTransactionExecutor
public CrossGroupTransactionExecutor(PartitionRouter router, GroupLockManager lockManager, @Nullable CrossGroupTransactionExecutor.RaftTransactionSubmitter raftSubmitter, Duration lockTimeout) Create a cross-group transaction executor with Raft-serialized transactions.- Parameters:
router- the partition routerlockManager- the group lock manager (used only in fallback mode)raftSubmitter- submits transactions through Raft consensus (null for local fallback)lockTimeout- maximum time to wait for group locks (fallback only)
-
-
Method Details
-
execute
public TransactionResult execute(Transaction transaction, Function<Integer, DistributedMap<String, String>> mapResolver) throws InterruptedExceptionExecute a cross-group transaction.The
mapResolverfunction maps group IDs to their DistributedMap instance. This allows the executor to access the correct map for each Raft group.- Parameters:
transaction- the transaction to executemapResolver- function that returns the DistributedMap for a given group ID- Returns:
- the transaction result
- Throws:
InterruptedException- if interrupted while acquiring locks
-
execute
public TransactionResult execute(ReplicatedTransactionCommand command, Function<Integer, DistributedMap<String, String>> mapResolver) throws InterruptedException- Throws:
InterruptedException
-
execute
public TransactionResult execute(ReplicatedTransactionCommand command, BiFunction<Integer, String, DistributedMap<String, String>> mapResolver) throws InterruptedException- Throws:
InterruptedException
-
applyCommittedTransaction
public TransactionResult applyCommittedTransaction(Transaction transaction, Function<Integer, DistributedMap<String, String>> mapResolver) Apply a Raft-committed transaction locally. Called by the state machine apply handler. Uses transactionLock on each map for local atomicity during condition eval + op execution.- Parameters:
transaction- the committed transaction to applymapResolver- function that returns the DistributedMap for a given group ID- Returns:
- the transaction result
-
applyCommittedTransaction
public TransactionResult applyCommittedTransaction(ReplicatedTransactionCommand command, Function<Integer, DistributedMap<String, String>> mapResolver) -
applyCommittedTransaction
public TransactionResult applyCommittedTransaction(ReplicatedTransactionCommand command, BiFunction<Integer, String, DistributedMap<String, String>> mapResolver) Apply a committed transaction using a per-op (groupId, mapName) → map resolver. This is the ESC-14 path that supports cross-group atomic BATCH where a single Raft group can carry operations targeting multiple logical maps.
-