Hi *,
Some thoughts I have about above JIRA.
Background:
CacheManager cm;
Cache c1 = cm.getCache("replicatedCacheConfig1");
Cache c2 = cm.getCache("replicatedCacheConfig2");
transactionManager.start();
c1.put(a,b);
c2.put(b,c);
transactionManager.commit(); // at this point there we replicate two
PrepareCommand and two CommitCommands , the JIRA is about aggregating
all prepares into one (same about commits) => less roundtrip
Considerations:
REPL: This functionality only makes sense if we have at least two active
replicated caches.
DIST: with DIST things can still be optimized in order to group
Prepare/Commit/RollbackCommands about to be replicated to the same nodes
If we have a tx spreading an ASYNC and an SYNC cache the optimization is
not supported for now.
Design notes:
GlobalTxRepository is (basically) a Map<Transaction, AtomicInt>: for
each Transaction it keeps an count(AtomicInt) of the caches that were
affected by a given Transaction.
Operations:
1. GlobalTxRepository.transactionRegistered(Transaction) will be called
whenever a TransactionXaAdapter is created. This will increment
Transaction's associated participant count. Call made from TransactionTable.
2. GlobalTxRepository.aboutToPrepare(Transaction) will be called when a
transaction is about to prepare, and will decrement the Transaction's
associated participant count. Call made from TxInterceptor
3. GlobalTxRepository.aboutToFinish(Transaction) will be called before a
transaction commits or rollbacks. Call made from TxInterceptor
ReplicationInterceptor and DistributionInterceptor:
In visitPrepare/visitCommit/visitRollback - will check if the
participant count associated with given tx is 0, if so will trigger
replication. This will make sure that only last participant will do the
actual replication.
Performance costs:
- there is a set of operations this functionality requires(map lookups,
atomic increments/decrements) which might be totally useless if user
won't use such transactions. There are some ways to reduce/avoid
performance costs:
a) only expose this functionality through Flags (extra Flag required.
Flag.OPTIMIZE_TX_REPLICATION ?)
b) allow the user to enable it statically through a configuration option
c) use a sort of ergonomics, for each 10th/n-th finishing transaction,
check weather it spread over more than one caches: if so enable the
functionality and keep it enabled for good
My personal vote is for b) for simplicity.
Any feedback much appreciated :)
Cheers,
Mircea