This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 42439684cb8 IGNITE-25541 Fix NPE on timeout during transaction 
initialization - Fixes #12125.
42439684cb8 is described below

commit 42439684cb8b944bb47cd555af6f78449349c616
Author: Aleksey Plekhanov <plehanov.a...@gmail.com>
AuthorDate: Tue Jun 10 11:22:54 2025 +0300

    IGNITE-25541 Fix NPE on timeout during transaction initialization - Fixes 
#12125.
    
    Signed-off-by: Aleksey Plekhanov <plehanov.a...@gmail.com>
---
 .../cache/distributed/near/GridNearTxLocal.java    | 19 ++++-
 .../cache/transactions/IgniteTxManager.java        |  6 +-
 .../TxTimeoutOnInitializationTest.java             | 80 ++++++++++++++++++++++
 .../ignite/testsuites/IgniteCacheTestSuite6.java   |  2 +
 4 files changed, 104 insertions(+), 3 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index e414eedd071..4ed59193af5 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -101,6 +101,7 @@ import org.apache.ignite.plugin.security.SecurityPermission;
 import org.apache.ignite.transactions.TransactionConcurrency;
 import org.apache.ignite.transactions.TransactionIsolation;
 import org.apache.ignite.transactions.TransactionState;
+import org.apache.ignite.transactions.TransactionTimeoutException;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
@@ -270,8 +271,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter 
implements GridTimeou
         this.txDumpsThrottling = txDumpsThrottling;
 
         initResult();
-
-        trackTimeout = timeout() > 0 && !implicit() && 
cctx.time().addTimeoutObject(this);
     }
 
     /** {@inheritDoc} */
@@ -4313,6 +4312,22 @@ public class GridNearTxLocal extends 
GridDhtTxLocalAdapter implements GridTimeou
         this.threadId = threadId;
     }
 
+    /**
+     * Starts tracking tx as timeout object.
+     */
+    public void initTimeoutHandler() throws TransactionTimeoutException {
+        if (timeout() > 0 && !implicit()) {
+            if (remainingTime() == -1L) {
+                onTimeout();
+
+                throw new TransactionTimeoutException(
+                    "Failed to start transaction. Transaction is timed out 
during initialization.");
+            }
+            else
+                trackTimeout = cctx.time().addTimeoutObject(this);
+        }
+    }
+
     /**
      * Removes timeout handler.
      *
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index e9cd1228322..5fb6fb51365 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -722,7 +722,11 @@ public class IgniteTxManager extends 
GridCacheSharedManagerAdapter {
 
         tx.applicationAttributes(appAttrs);
 
-        return onCreated(sysCacheCtx, tx);
+        onCreated(sysCacheCtx, tx);
+
+        tx.initTimeoutHandler();
+
+        return tx;
     }
 
     /**
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxTimeoutOnInitializationTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxTimeoutOnInitializationTest.java
new file mode 100644
index 00000000000..569ddf43449
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxTimeoutOnInitializationTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.transactions;
+
+import org.apache.ignite.Ignition;
+import org.apache.ignite.client.ClientTransaction;
+import org.apache.ignite.client.Config;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static 
org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static 
org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ * Tests transaction timeout during initialization.
+ */
+public class TxTimeoutOnInitializationTest extends GridCommonAbstractTest {
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testTxTimeoutOnInitialization() throws Exception {
+        long txTimeout = 500L;
+
+        IgniteEx ignite0 = startGrid(0);
+
+        GridCacheSharedContext<?, ?> sharedCtx = 
ignite0.context().cache().context();
+
+        IgniteTxManager tm = Mockito.spy(sharedCtx.tm());
+        sharedCtx.setTxManager(tm);
+
+        Mockito.doAnswer(m -> {
+            doSleep(txTimeout * 2);
+
+            return m.callRealMethod();
+        }).when(tm).onCreated(Mockito.any(), Mockito.any());
+
+        try (Transaction tx = ignite0.transactions().txStart(PESSIMISTIC, 
REPEATABLE_READ, txTimeout, 1)) {
+            // No-op.
+        }
+        catch (Exception e) {
+            assertTrue(e.getMessage().contains("timed out"));
+        }
+
+        assertTrue(GridTestUtils.waitForCondition(() -> 
tm.activeTransactions().isEmpty(), 1_000L));
+
+        try (IgniteClient client = Ignition.startClient(new 
ClientConfiguration().setAddresses(Config.SERVER))) {
+            try (ClientTransaction tx = 
client.transactions().txStart(PESSIMISTIC, REPEATABLE_READ, txTimeout)) {
+                // No-op.
+            }
+            catch (Exception e) {
+                assertTrue(e.getMessage().contains("timed out"));
+            }
+        }
+
+        assertTrue(GridTestUtils.waitForCondition(() -> 
tm.activeTransactions().isEmpty(), 1_000L));
+    }
+}
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
index 1da50af28ac..eecf72df48c 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
@@ -70,6 +70,7 @@ import 
org.apache.ignite.internal.processors.cache.transactions.TxRollbackOnTime
 import 
org.apache.ignite.internal.processors.cache.transactions.TxRollbackOnTimeoutTest;
 import 
org.apache.ignite.internal.processors.cache.transactions.TxRollbackOnTopologyChangeTest;
 import 
org.apache.ignite.internal.processors.cache.transactions.TxStateChangeEventTest;
+import 
org.apache.ignite.internal.processors.cache.transactions.TxTimeoutOnInitializationTest;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.DynamicSuite;
 import org.junit.runner.RunWith;
@@ -111,6 +112,7 @@ public class IgniteCacheTestSuite6 {
         GridTestUtils.addTestIfNeeded(suite, 
TxRollbackAsyncNearCacheTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, 
TxRollbackOnTopologyChangeTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, 
TxRollbackOnTimeoutOnePhaseCommitTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, 
TxTimeoutOnInitializationTest.class, ignoredTests);
 
         GridTestUtils.addTestIfNeeded(suite, 
TxOptimisticPrepareOnUnstableTopologyTest.class, ignoredTests);
 

Reply via email to