[ 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)