This is an automated email from the ASF dual-hosted git repository. gvvinblade 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 df92048 IGNITE-10415: MVCC TX: Exception handling fixed. This closes #6030. df92048 is described below commit df9204841069e176a14e654a7636f88b5a2673cd Author: Andrey V. Mashenkov <andrey.mashen...@gmail.com> AuthorDate: Thu Feb 14 16:12:19 2019 +0300 IGNITE-10415: MVCC TX: Exception handling fixed. This closes #6030. --- .../internal/processors/cache/mvcc/MvccUtils.java | 7 ++- .../processors/odbc/jdbc/JdbcRequestHandler.java | 3 ++ .../processors/odbc/odbc/OdbcRequestHandler.java | 3 ++ .../internal/processors/query/QueryUtils.java | 6 +++ .../IgniteTxAlreadyCompletedCheckedException.java | 36 +++++++++++++++ .../apache/ignite/internal/util/IgniteUtils.java | 8 ++++ .../TransactionAlreadyCompletedException.java | 37 +++++++++++++++ .../TxRollbackOnIncorrectParamsTest.java | 54 ++++++++++++++++------ .../processors/query/h2/IgniteH2Indexing.java | 20 ++++---- .../query/h2/twostep/GridReduceQueryExecutor.java | 11 ++++- 10 files changed, 156 insertions(+), 29 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java index 9d688c5..f904966 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java @@ -31,7 +31,7 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageI import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; import org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.processors.query.IgniteSQLException; +import org.apache.ignite.internal.transactions.IgniteTxAlreadyCompletedCheckedException; import org.apache.ignite.internal.transactions.IgniteTxUnexpectedStateCheckedException; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.transactions.TransactionException; @@ -43,7 +43,6 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; import static org.apache.ignite.internal.pagemem.PageIdUtils.itemId; import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId; import static org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO.MVCC_INFO_SIZE; -import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.TRANSACTION_COMPLETED; import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; @@ -678,9 +677,9 @@ public class MvccUtils { * @param tx Transaction. * @return Checked transaction. */ - public static GridNearTxLocal checkActive(GridNearTxLocal tx) { + public static GridNearTxLocal checkActive(GridNearTxLocal tx) throws IgniteTxAlreadyCompletedCheckedException { if (tx != null && tx.state() != TransactionState.ACTIVE) - throw new IgniteSQLException("Transaction is already completed.", TRANSACTION_COMPLETED); + throw new IgniteTxAlreadyCompletedCheckedException("Transaction is already completed."); return tx; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java index 35bb2a9..7a28a19 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java @@ -64,6 +64,7 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteBiTuple; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionDuplicateKeyException; import org.apache.ignite.transactions.TransactionSerializationException; @@ -1116,6 +1117,8 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler { return new JdbcResponse(IgniteQueryErrorCode.QUERY_CANCELED, e.getMessage()); if (e instanceof TransactionSerializationException) return new JdbcResponse(IgniteQueryErrorCode.TRANSACTION_SERIALIZATION_ERROR, e.getMessage()); + if (e instanceof TransactionAlreadyCompletedException) + return new JdbcResponse(IgniteQueryErrorCode.TRANSACTION_COMPLETED, e.getMessage()); if (e instanceof TransactionDuplicateKeyException) return new JdbcResponse(IgniteQueryErrorCode.DUPLICATE_KEY, e.getMessage()); if (e instanceof MvccUtils.NonMvccTransactionException) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java index 01ceb59..43fedae 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java @@ -62,6 +62,7 @@ import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteBiTuple; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionDuplicateKeyException; import org.apache.ignite.transactions.TransactionSerializationException; @@ -974,6 +975,8 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { if (e instanceof TransactionSerializationException) return new OdbcResponse(IgniteQueryErrorCode.TRANSACTION_SERIALIZATION_ERROR, msg); + if (e instanceof TransactionAlreadyCompletedException) + return new OdbcResponse(IgniteQueryErrorCode.TRANSACTION_COMPLETED, msg); if (e instanceof MvccUtils.NonMvccTransactionException) return new OdbcResponse(IgniteQueryErrorCode.TRANSACTION_TYPE_MISMATCH, msg); if (e instanceof MvccUtils.UnsupportedTxModeException) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java index e15687e..da9279d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java @@ -67,6 +67,7 @@ import org.apache.ignite.internal.processors.query.schema.SchemaOperationExcepti import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.A; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionDuplicateKeyException; import org.apache.ignite.transactions.TransactionSerializationException; import org.jetbrains.annotations.NotNull; @@ -1501,6 +1502,11 @@ public class QueryUtils { sqlState = IgniteQueryErrorCode.codeToSqlState(code); } + else if (e instanceof TransactionAlreadyCompletedException){ + code = IgniteQueryErrorCode.TRANSACTION_COMPLETED; + + sqlState = IgniteQueryErrorCode.codeToSqlState(code); + } else { sqlState = SqlStateCode.INTERNAL_ERROR; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/transactions/IgniteTxAlreadyCompletedCheckedException.java b/modules/core/src/main/java/org/apache/ignite/internal/transactions/IgniteTxAlreadyCompletedCheckedException.java new file mode 100644 index 0000000..47b47bc --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/transactions/IgniteTxAlreadyCompletedCheckedException.java @@ -0,0 +1,36 @@ +/* + * 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.transactions; + +/** + * Exception thrown whenever Mvcc transaction has been finished before operation finished. + * E.g. rollback due to some reason. + */ +public class IgniteTxAlreadyCompletedCheckedException extends TransactionCheckedException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message. + * + * @param msg Error message. + */ + public IgniteTxAlreadyCompletedCheckedException(String msg) { + super(msg); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 51feab6..8fb0a70 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -211,6 +211,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAttributes; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheSharedContext; import org.apache.ignite.internal.processors.cluster.BaselineTopology; +import org.apache.ignite.internal.transactions.IgniteTxAlreadyCompletedCheckedException; import org.apache.ignite.internal.transactions.IgniteTxDuplicateKeyCheckedException; import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException; import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException; @@ -252,6 +253,7 @@ import org.apache.ignite.spi.IgniteSpi; import org.apache.ignite.spi.IgniteSpiException; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.DiscoverySpiOrderSupport; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionDeadlockException; import org.apache.ignite.transactions.TransactionDuplicateKeyException; import org.apache.ignite.transactions.TransactionHeuristicException; @@ -974,6 +976,12 @@ public abstract class IgniteUtils { } }); + m.put(IgniteTxAlreadyCompletedCheckedException.class, new C1<IgniteCheckedException, IgniteException>() { + @Override public IgniteException apply(IgniteCheckedException e) { + return new TransactionAlreadyCompletedException(e.getMessage(), e); + } + }); + return m; } diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionAlreadyCompletedException.java b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionAlreadyCompletedException.java new file mode 100644 index 0000000..e30cb27 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionAlreadyCompletedException.java @@ -0,0 +1,37 @@ +/* + * 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.transactions; + +/** + * Exception thrown whenever Mvcc transaction has been finished before operation finished. + * E.g. rollback due to some reason. + */ +public class TransactionAlreadyCompletedException extends TransactionException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message and optional nested exception. + * + * @param msg Error message. + * @param cause Optional nested exception (can be {@code null}). + */ + public TransactionAlreadyCompletedException(String msg, Throwable cause) { + super(cause); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRollbackOnIncorrectParamsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRollbackOnIncorrectParamsTest.java index b69a70e..c421f26 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRollbackOnIncorrectParamsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxRollbackOnIncorrectParamsTest.java @@ -28,8 +28,10 @@ import org.apache.ignite.events.TransactionStateChangedEvent; import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.MvccFeatureChecker; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.transactions.Transaction; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionConcurrency; import org.apache.ignite.transactions.TransactionIsolation; import org.apache.ignite.transactions.TransactionRollbackException; @@ -79,7 +81,10 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } catch (CacheException ex) { - assertTrue(ex.getCause() instanceof TransactionRollbackException); + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } try (Transaction tx = ignite.transactions().txStart()) { @@ -90,7 +95,10 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } catch (CacheException ex) { - assertTrue(ex.getCause() instanceof TransactionRollbackException); + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } } @@ -129,8 +137,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } } @@ -179,8 +190,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } try (Transaction tx = remote.transactions().txStart()) { @@ -190,8 +204,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } } @@ -242,8 +259,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } try (Transaction tx = remote.transactions().txStart()) { @@ -253,8 +273,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } } @@ -306,8 +329,11 @@ public class TxRollbackOnIncorrectParamsTest extends GridCommonAbstractTest { fail("Should fail prior this line."); } - catch (CacheException ignored) { - // No-op. + catch (CacheException ex) { + if (MvccFeatureChecker.forcedMvcc()) + assertTrue(ex.toString(), ex.getCause() instanceof TransactionAlreadyCompletedException); + else + assertTrue(ex.toString(), ex.getCause() instanceof TransactionRollbackException); } assertFalse(rollbackFailed.get()); diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 88a72e8..621d6e8 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -96,15 +96,6 @@ import org.apache.ignite.internal.processors.query.RunningQueryManager; import org.apache.ignite.internal.processors.query.SqlClientContext; import org.apache.ignite.internal.processors.query.UpdateSourceIterator; import org.apache.ignite.internal.processors.query.h2.affinity.H2PartitionResolver; -import org.apache.ignite.internal.processors.query.h2.dml.DmlDistributedPlanInfo; -import org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateResultsIterator; -import org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateSingleEntryIterator; -import org.apache.ignite.internal.processors.query.h2.dml.UpdateMode; -import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder; -import org.apache.ignite.internal.processors.query.h2.opt.QueryContext; -import org.apache.ignite.internal.processors.query.h2.opt.QueryContextRegistry; -import org.apache.ignite.internal.processors.query.h2.twostep.PartitionReservationManager; -import org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult; import org.apache.ignite.internal.processors.query.h2.affinity.PartitionExtractor; import org.apache.ignite.internal.processors.query.h2.database.H2TreeClientIndex; import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; @@ -114,10 +105,17 @@ import org.apache.ignite.internal.processors.query.h2.database.io.H2InnerIO; import org.apache.ignite.internal.processors.query.h2.database.io.H2LeafIO; import org.apache.ignite.internal.processors.query.h2.database.io.H2MvccInnerIO; import org.apache.ignite.internal.processors.query.h2.database.io.H2MvccLeafIO; +import org.apache.ignite.internal.processors.query.h2.dml.DmlDistributedPlanInfo; +import org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateResultsIterator; +import org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateSingleEntryIterator; import org.apache.ignite.internal.processors.query.h2.dml.DmlUtils; +import org.apache.ignite.internal.processors.query.h2.dml.UpdateMode; import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan; +import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder; import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; +import org.apache.ignite.internal.processors.query.h2.opt.QueryContext; +import org.apache.ignite.internal.processors.query.h2.opt.QueryContextRegistry; import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias; import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst; import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser; @@ -126,6 +124,7 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable; import org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor; import org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor; import org.apache.ignite.internal.processors.query.h2.twostep.MapQueryLazyWorker; +import org.apache.ignite.internal.processors.query.h2.twostep.PartitionReservationManager; import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2QueryRequest; import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitor; import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure; @@ -133,6 +132,7 @@ import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisito import org.apache.ignite.internal.sql.command.SqlCommand; import org.apache.ignite.internal.sql.command.SqlCommitTransactionCommand; import org.apache.ignite.internal.sql.command.SqlRollbackTransactionCommand; +import org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap; import org.apache.ignite.internal.util.GridEmptyCloseableIterator; import org.apache.ignite.internal.util.GridSpinBusyLock; @@ -1269,7 +1269,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { }; } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw U.convertException(e); } } diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java index 046840e..24e93cd 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java @@ -82,6 +82,7 @@ import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2DmlReque import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2DmlResponse; import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2QueryRequest; import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2SelectForUpdateTxDetails; +import org.apache.ignite.internal.transactions.IgniteTxAlreadyCompletedCheckedException; import org.apache.ignite.internal.util.GridSpinBusyLock; import org.apache.ignite.internal.util.typedef.C2; import org.apache.ignite.internal.util.typedef.CIX2; @@ -92,6 +93,7 @@ import org.apache.ignite.lang.IgniteBiClosure; import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.transactions.TransactionAlreadyCompletedException; import org.apache.ignite.transactions.TransactionException; import org.h2.command.ddl.CreateTableData; import org.h2.engine.Session; @@ -462,7 +464,14 @@ public class GridReduceQueryExecutor { boolean mvccEnabled = mvccEnabled(ctx); - final GridNearTxLocal curTx = mvccEnabled ? checkActive(tx(ctx)) : null; + final GridNearTxLocal curTx; + + try { + curTx = mvccEnabled ? checkActive(tx(ctx)) : null; + } + catch (IgniteTxAlreadyCompletedCheckedException e) { + throw new TransactionAlreadyCompletedException(e.getMessage(), e); + } final GridNearTxSelectForUpdateFuture sfuFut;