You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Vyacheslav Koptilin (Jira)" <ji...@apache.org> on 2024/12/10 10:36:00 UTC

[jira] [Assigned] (IGNITE-23467) Resolve all abandoned locks for the key at a time

     [ https://issues.apache.org/jira/browse/IGNITE-23467?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Vyacheslav Koptilin reassigned IGNITE-23467:
--------------------------------------------

    Assignee: Vladislav Pyatkov

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