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 40f6d16a79 IGNITE-18892 Implement ClientTransaction.isReadonly and 
readTimestamp (#1715)
40f6d16a79 is described below

commit 40f6d16a79e22a71f1837a54b333ff0f727e72d5
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Tue Feb 28 11:32:22 2023 +0300

    IGNITE-18892 Implement ClientTransaction.isReadonly and readTimestamp 
(#1715)
---
 .../java/org/apache/ignite/tx/Transaction.java     |  3 ++-
 .../requests/tx/ClientTransactionBeginRequest.java | 15 ++++++++++++---
 .../internal/client/tx/ClientTransaction.java      | 18 +++++++++++++-----
 .../internal/client/tx/ClientTransactions.java     | 20 ++++++++++++++++++--
 .../RepeatedFinishClientTransactionTest.java       |  8 ++++----
 .../app/client/ItThinClientTransactionsTest.java   | 22 ++++++++++++++++++++++
 6 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/modules/api/src/main/java/org/apache/ignite/tx/Transaction.java 
b/modules/api/src/main/java/org/apache/ignite/tx/Transaction.java
index 0070413267..5d647c436b 100644
--- a/modules/api/src/main/java/org/apache/ignite/tx/Transaction.java
+++ b/modules/api/src/main/java/org/apache/ignite/tx/Transaction.java
@@ -19,6 +19,7 @@ package org.apache.ignite.tx;
 
 import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * The transaction.
@@ -68,5 +69,5 @@ public interface Transaction {
      *
      * @return Read timestamp for the given transaction if it is a read-only 
one or {code null} otherwise.
      */
-    HybridTimestamp readTimestamp();
+    @Nullable HybridTimestamp readTimestamp();
 }
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/tx/ClientTransactionBeginRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/tx/ClientTransactionBeginRequest.java
index 15e6890022..a3476835ab 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/tx/ClientTransactionBeginRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/tx/ClientTransactionBeginRequest.java
@@ -51,12 +51,21 @@ public class ClientTransactionBeginRequest {
             options = new TransactionOptions().readOnly(true);
         }
 
-        return transactions.beginAsync(options).thenAccept(t -> {
+        return transactions.beginAsync(options).thenAccept(tx -> {
             try {
-                long resourceId = resources.put(new ClientResource(t, 
t::rollbackAsync));
+                long resourceId = resources.put(new ClientResource(tx, 
tx::rollbackAsync));
                 out.packLong(resourceId);
+
+                var readTs = tx.readTimestamp();
+
+                if (readTs != null) {
+                    out.packLong(readTs.getPhysical());
+                    out.packInt(readTs.getLogical());
+                } else {
+                    out.packNil();
+                }
             } catch (IgniteInternalCheckedException e) {
-                t.rollback();
+                tx.rollback();
                 throw new IgniteInternalException(e.getMessage(), e);
             }
         });
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 9448579b7b..dd8c4ec4d3 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
@@ -29,6 +29,7 @@ import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.tx.Transaction;
 import org.apache.ignite.tx.TransactionException;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Client transaction.
@@ -43,15 +44,24 @@ public class ClientTransaction implements Transaction {
     /** The future used on repeated commit/rollback. */
     private final AtomicReference<CompletableFuture<Void>> finishFut = new 
AtomicReference<>();
 
+    /** Read-only flag. */
+    private final boolean isReadOnly;
+
+    /** Read timestamp. */
+    @Nullable
+    private final HybridTimestamp readTs;
+
     /**
      * Constructor.
      *
      * @param ch Channel that the transaction belongs to.
      * @param id Transaction id.
      */
-    public ClientTransaction(ClientChannel ch, long id) {
+    public ClientTransaction(ClientChannel ch, long id, boolean isReadOnly, 
@Nullable HybridTimestamp readTs) {
         this.ch = ch;
         this.id = id;
+        this.isReadOnly = isReadOnly;
+        this.readTs = readTs;
     }
 
     /**
@@ -115,15 +125,13 @@ public class ClientTransaction implements Transaction {
     /** {@inheritDoc} */
     @Override
     public boolean isReadOnly() {
-        // TODO: IGNITE-17929 Add read-only support to ClientTransactions
-        return false;
+        return isReadOnly;
     }
 
     /** {@inheritDoc} */
     @Override
     public HybridTimestamp readTimestamp() {
-        // TODO: IGNITE-17929 Add read-only support to ClientTransactions
-        throw new UnsupportedOperationException("Not implemented yet.");
+        return readTs;
     }
 
     /**
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
index e905d18beb..e77e4bba26 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/tx/ClientTransactions.java
@@ -20,11 +20,15 @@ package org.apache.ignite.internal.client.tx;
 import static org.apache.ignite.internal.client.ClientUtils.sync;
 
 import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.client.PayloadInputChannel;
 import org.apache.ignite.internal.client.ReliableChannel;
+import org.apache.ignite.internal.client.proto.ClientMessageUnpacker;
 import org.apache.ignite.internal.client.proto.ClientOp;
+import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.tx.IgniteTransactions;
 import org.apache.ignite.tx.Transaction;
 import org.apache.ignite.tx.TransactionOptions;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -57,9 +61,21 @@ public class ClientTransactions implements 
IgniteTransactions {
             throw new UnsupportedOperationException("Timeouts are not 
supported yet");
         }
 
+        boolean readOnly = options != null && options.readOnly();
+
         return ch.serviceAsync(
                 ClientOp.TX_BEGIN,
-                w -> w.out().packBoolean(options != null && 
options.readOnly()),
-                r -> new ClientTransaction(r.clientChannel(), 
r.in().unpackLong()));
+                w -> w.out().packBoolean(readOnly),
+                r -> readTx(r, readOnly));
+    }
+
+    @NotNull
+    private static ClientTransaction readTx(PayloadInputChannel r, boolean 
isReadOnly) {
+        ClientMessageUnpacker in = r.in();
+
+        long id = in.unpackLong();
+        HybridTimestamp readTs = in.tryUnpackNil() ? null : new 
HybridTimestamp(in.unpackLong(), in.unpackInt());
+
+        return new ClientTransaction(r.clientChannel(), id, isReadOnly, 
readTs);
     }
 }
diff --git 
a/modules/client/src/test/java/org/apache/ignite/internal/client/RepeatedFinishClientTransactionTest.java
 
b/modules/client/src/test/java/org/apache/ignite/internal/client/RepeatedFinishClientTransactionTest.java
index 7ffdf1010a..6115cd0885 100644
--- 
a/modules/client/src/test/java/org/apache/ignite/internal/client/RepeatedFinishClientTransactionTest.java
+++ 
b/modules/client/src/test/java/org/apache/ignite/internal/client/RepeatedFinishClientTransactionTest.java
@@ -47,7 +47,7 @@ public class RepeatedFinishClientTransactionTest {
 
         TestClientChannel clientChannel = new 
TestClientChannel(txFinishStartedLatch, secondFinishLatch);
 
-        ClientTransaction tx = new ClientTransaction(clientChannel, 1);
+        ClientTransaction tx = new ClientTransaction(clientChannel, 1, false, 
null);
 
         CompletableFuture<Object> fut = new CompletableFuture<>();
 
@@ -85,7 +85,7 @@ public class RepeatedFinishClientTransactionTest {
 
         TestClientChannel clientChannel = new 
TestClientChannel(txFinishStartedLatch, secondFinishLatch);
 
-        ClientTransaction tx = new ClientTransaction(clientChannel, 1);
+        ClientTransaction tx = new ClientTransaction(clientChannel, 1, false, 
null);
 
         CompletableFuture<Object> fut = new CompletableFuture<>();
 
@@ -122,7 +122,7 @@ public class RepeatedFinishClientTransactionTest {
 
         when(clientChannel.serviceAsync(anyInt(), any(), 
any())).thenReturn(failedFuture(new Exception("Expected exception.")));
 
-        ClientTransaction tx = new ClientTransaction(clientChannel, 1);
+        ClientTransaction tx = new ClientTransaction(clientChannel, 1, false, 
null);
 
         CompletableFuture<Object> fut = new CompletableFuture<>();
 
@@ -148,7 +148,7 @@ public class RepeatedFinishClientTransactionTest {
 
         when(clientChannel.serviceAsync(anyInt(), any(), 
any())).thenReturn(failedFuture(new Exception("Expected exception.")));
 
-        ClientTransaction tx = new ClientTransaction(clientChannel, 1);
+        ClientTransaction tx = new ClientTransaction(clientChannel, 1, false, 
null);
 
         CompletableFuture<Object> fut = new CompletableFuture<>();
 
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
index e38a31ae4d..dd2b77777b 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
@@ -22,6 +22,8 @@ import static org.hamcrest.Matchers.containsString;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -326,6 +328,26 @@ public class ItThinClientTransactionsTest extends 
ItAbstractThinClientTest {
         }
     }
 
+    @Test
+    void testReadOnlyTxHasReadTimestamp() {
+        Transaction tx = client().transactions().begin(new 
TransactionOptions().readOnly(true));
+
+        assertTrue(tx.isReadOnly());
+        assertNotNull(tx.readTimestamp());
+
+        tx.rollback();
+    }
+
+    @Test
+    void testReadWriteTxHasNoReadTimestamp() {
+        Transaction tx = client().transactions().begin();
+
+        assertFalse(tx.isReadOnly());
+        assertNull(tx.readTimestamp());
+
+        tx.rollback();
+    }
+
     private KeyValueView<Integer, String> kvView() {
         return table().keyValueView(Mapper.of(Integer.class), 
Mapper.of(String.class));
     }

Reply via email to