[
https://issues.apache.org/jira/browse/IGNITE-23467?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Vladislav Pyatkov updated IGNITE-23467:
---------------------------------------
Release Note: Accelerated rollback abandoned transactions on a lock
conflict with another transaction. (was: Accelerated reverting abandoned
transactions on a lock conflict with another transaction.)
> Resolve all abandoned locks for the key at a time
> -------------------------------------------------
>
> Key: IGNITE-23467
> URL: https://issues.apache.org/jira/browse/IGNITE-23467
> Project: Ignite
> Issue Type: Improvement
> Reporter: Alexander Lapin
> Assignee: Vladislav Pyatkov
> Priority: Major
> Labels: ignite-3
> Fix For: 3.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> h3. Motivation
> Currently only first abandoned lock will be resolved within abandoned lock
> resolution process. Precisely only one transaction that holds that lock will
> be resolved. That will work way ineffective in case of chain of multiple
> abandoned locks, e.g. S locks acquired by different transacions.
> h3. Definition of Done
> * Any abandoned lock resolution procedure (and currently we have only one -
> another tx touch) should resolve whole chain of locks for the touched entity.
> *Reproducer (put in ItTransactionRecoveryTest)*
> {code:java}
> @Test
> public void testMultipleAbandonedTxsAreAborted() throws Exception {
> TableImpl tbl = unwrapTableImpl(node(0).tables().table(TABLE_NAME));
> var tblReplicationGrp = new TablePartitionId(tbl.tableId(), PART_ID);
> String leaseholder = waitAndGetLeaseholder(node(0), tblReplicationGrp);
> IgniteImpl commitPartNode = findNodeByName(leaseholder);
> log.info("Transaction commit partition is determined [node={}].",
> commitPartNode.name());
> IgniteImpl txCrdNode = nonPrimaryNode(leaseholder);
> log.info("Transaction coordinator is chosen [node={}].",
> txCrdNode.name());
> RecordView<Tuple> view =
> txCrdNode.tables().table(TABLE_NAME).recordView();
> view.upsert(null, Tuple.create().set("key", 42).set("val", "val1"));
> List<InternalTransaction> txns = new ArrayList<>();
> for (int i = 0; i < 10; i++) {
> InternalTransaction tx = (InternalTransaction)
> txCrdNode.transactions().begin();
> Tuple ignored = view.get(tx, Tuple.create().set("key", 42));
> txns.add(tx);
> }
> LockManager lockManager = commitPartNode.txManager().lockManager();
> for (InternalTransaction txn : txns) {
> Iterator<Lock> locks = lockManager.locks(txn.id());
> assertTrue(locks.hasNext());
> }
> txCrdNode.stop();
> assertTrue(waitForCondition(
> () -> node(0).clusterNodes().stream().filter(n ->
> txCrdNode.id().equals(n.id())).count() == 0,
> 10_000));
> InternalTransaction conflictTx = (InternalTransaction)
> node(0).transactions().begin();
> runConflictingTransaction(node(0), conflictTx);
> // Test if all abandoned transactions are aborted.
> for (InternalTransaction txn : txns) {
> assertTrue(
> waitForCondition(() -> txStoredState(commitPartNode,
> txn.id()) == TxState.ABORTED, 10_000),
> txns.stream().map(tx -> IgniteStringFormatter.format(
> "\n{} -> {}",
> tx.id(),
> txStoredMeta(commitPartNode, tx.id())
> )).collect(Collectors.joining(","))
> );
> }
> }
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)