You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2023/12/19 09:23:04 UTC
(ignite-3) branch main updated: IGNITE-20598 Java client: Fix incorrect error for query on closed transaction (#2972)
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new c6d00df24f IGNITE-20598 Java client: Fix incorrect error for query on closed transaction (#2972)
c6d00df24f is described below
commit c6d00df24f0385590de7c0ffd149ac73c0d26028
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Tue Dec 19 11:22:58 2023 +0200
IGNITE-20598 Java client: Fix incorrect error for query on closed transaction (#2972)
* Add local tx state check - disallow using finished tx
* Wrap all `ClientSession` exceptions in `SqlException` (match embedded API behavior)
Also fixes [IGNITE-20742 Thin client cannot find the resource when it is trying to execute an operation on the finalized transaction](https://issues.apache.org/jira/browse/IGNITE-20742)
---
.../ignite/internal/client/sql/ClientSession.java | 10 ++++--
.../internal/client/tx/ClientTransaction.java | 38 +++++++++++++++++++++-
.../sql/api/ItSqlClientAsynchronousApiTest.java | 12 -------
.../sql/api/ItSqlClientSynchronousApiTest.java | 12 -------
4 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSession.java b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSession.java
index 59e242baac..5d6e739683 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSession.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSession.java
@@ -37,12 +37,14 @@ import org.apache.ignite.internal.client.proto.ClientOp;
import org.apache.ignite.internal.client.tx.ClientTransaction;
import org.apache.ignite.internal.sql.AbstractSession;
import org.apache.ignite.sql.BatchedArguments;
+import org.apache.ignite.sql.SqlException;
import org.apache.ignite.sql.SqlRow;
import org.apache.ignite.sql.Statement;
import org.apache.ignite.sql.async.AsyncResultSet;
import org.apache.ignite.sql.reactive.ReactiveResultSet;
import org.apache.ignite.table.mapper.Mapper;
import org.apache.ignite.tx.Transaction;
+import org.apache.ignite.tx.TransactionException;
import org.jetbrains.annotations.Nullable;
/**
@@ -166,8 +168,12 @@ public class ClientSession implements AbstractSession {
PayloadReader<AsyncResultSet<T>> payloadReader = r -> new ClientAsyncResultSet<>(r.clientChannel(), r.in(), mapper);
if (transaction != null) {
- //noinspection resource
- return ClientTransaction.get(transaction).channel().serviceAsync(ClientOp.SQL_EXEC, payloadWriter, payloadReader);
+ try {
+ //noinspection resource
+ return ClientTransaction.get(transaction).channel().serviceAsync(ClientOp.SQL_EXEC, payloadWriter, payloadReader);
+ } catch (TransactionException e) {
+ return CompletableFuture.failedFuture(new SqlException(e.traceId(), e.code(), e.getMessage(), e));
+ }
}
return ch.serviceAsync(ClientOp.SQL_EXEC, payloadWriter, payloadReader);
diff --git a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
index 57bbcb2793..ecfe99694f 100644
--- a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
+++ b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransaction.java
@@ -18,9 +18,12 @@
package org.apache.ignite.internal.client.tx;
import static org.apache.ignite.internal.client.ClientUtils.sync;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
+import static org.apache.ignite.lang.ErrorGroups.Transactions.TX_FAILED_READ_WRITE_OPERATION_ERR;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.internal.client.ClientChannel;
import org.apache.ignite.internal.client.proto.ClientOp;
@@ -32,6 +35,15 @@ import org.apache.ignite.tx.TransactionException;
* Client transaction.
*/
public class ClientTransaction implements Transaction {
+ /** Open state. */
+ private static final int STATE_OPEN = 0;
+
+ /** Committed state. */
+ private static final int STATE_COMMITTED = 1;
+
+ /** Rolled back state. */
+ private static final int STATE_ROLLED_BACK = 2;
+
/** Channel that the transaction belongs to. */
private final ClientChannel ch;
@@ -41,6 +53,9 @@ public class ClientTransaction implements Transaction {
/** The future used on repeated commit/rollback. */
private final AtomicReference<CompletableFuture<Void>> finishFut = new AtomicReference<>();
+ /** State. */
+ private final AtomicInteger state = new AtomicInteger(STATE_OPEN);
+
/** Read-only flag. */
private final boolean isReadOnly;
@@ -87,6 +102,8 @@ public class ClientTransaction implements Transaction {
return finishFut.get();
}
+ setState(STATE_COMMITTED);
+
CompletableFuture<Void> mainFinishFut = ch.serviceAsync(ClientOp.TX_COMMIT, w -> w.out().packLong(id), r -> null);
mainFinishFut.handle((res, e) -> finishFut.get().complete(null));
@@ -107,6 +124,8 @@ public class ClientTransaction implements Transaction {
return finishFut.get();
}
+ setState(STATE_ROLLED_BACK);
+
CompletableFuture<Void> mainFinishFut = ch.serviceAsync(ClientOp.TX_ROLLBACK, w -> w.out().packLong(id), r -> null);
mainFinishFut.handle((res, e) -> finishFut.get().complete(null));
@@ -134,6 +153,23 @@ public class ClientTransaction implements Transaction {
+ "'. Use IgniteClient.transactions() to start transactions.");
}
- return (ClientTransaction) tx;
+ ClientTransaction clientTx = (ClientTransaction) tx;
+
+ int state = clientTx.state.get();
+
+ if (state == STATE_OPEN) {
+ return clientTx;
+ }
+
+ // Match org.apache.ignite.internal.tx.TxState enum:
+ String stateStr = state == STATE_COMMITTED ? "COMMITTED" : "ABORTED";
+
+ throw new TransactionException(
+ TX_FAILED_READ_WRITE_OPERATION_ERR,
+ format("Transaction is already finished [id={}, state={}].", clientTx.id, stateStr));
+ }
+
+ private void setState(int state) {
+ this.state.compareAndExchange(STATE_OPEN, state);
}
}
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientAsynchronousApiTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientAsynchronousApiTest.java
index 2b2e174fd3..601fd00d57 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientAsynchronousApiTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientAsynchronousApiTest.java
@@ -56,16 +56,4 @@ public class ItSqlClientAsynchronousApiTest extends ItSqlAsynchronousApiTest {
public void closeSession() {
super.closeSession();
}
-
- @Override
- @Disabled("https://issues.apache.org/jira/browse/IGNITE-20598")
- public void checkTransactionsWithDml() {
- super.checkTransactionsWithDml();
- }
-
- @Override
- @Disabled("https://issues.apache.org/jira/browse/IGNITE-20742")
- public void testLockIsNotReleasedAfterTxRollback() {
- super.testLockIsNotReleasedAfterTxRollback();
- }
}
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
index fa48bff50f..b359975153 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlClientSynchronousApiTest.java
@@ -56,16 +56,4 @@ public class ItSqlClientSynchronousApiTest extends ItSqlSynchronousApiTest {
public void closeSession() {
super.closeSession();
}
-
- @Override
- @Disabled("https://issues.apache.org/jira/browse/IGNITE-20598")
- public void checkTransactionsWithDml() {
- super.checkTransactionsWithDml();
- }
-
- @Override
- @Disabled("https://issues.apache.org/jira/browse/IGNITE-20742")
- public void testLockIsNotReleasedAfterTxRollback() {
- super.testLockIsNotReleasedAfterTxRollback();
- }
}