From 58ef1fe68bc9a6f1880593485f3fb93ab8ce5232 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:14:17 +0000 Subject: [PATCH 1/7] chore(main): release 6.62.2-SNAPSHOT (#2983) :robot: I have created a release *beep* *boop* --- ### Updating meta-information for bleeding-edge SNAPSHOT release. --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- google-cloud-spanner-bom/pom.xml | 18 ++++++++--------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++---------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++---------- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 939adc492ea..18e1b8680e5 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.62.1 + 6.62.2-SNAPSHOT pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.62.1 + 6.62.2-SNAPSHOT com.google.cloud google-cloud-spanner test-jar - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 2ddb93b5371..f163b67618f 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.62.1 + 6.62.2-SNAPSHOT jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index c6959c55fd7..b9102aef691 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.62.1 + 6.62.2-SNAPSHOT jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 97f85ab5fdc..45e2e4ef867 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index 0ab8b79b3e5..3823c47d795 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index f04c003621b..559607c04c2 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.62.1 + 6.62.2-SNAPSHOT grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index fe934386b0d..ada78070399 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 4ff60c2b9e2..0e51c1f2cf4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.62.1 + 6.62.2-SNAPSHOT Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -61,47 +61,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT com.google.cloud google-cloud-spanner - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 3770eebaad2..2e9cca5344a 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.1 + 6.62.2-SNAPSHOT proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index 1ab3f6ec5d8..e8bd6a96863 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.1 + 6.62.2-SNAPSHOT proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index ed63e21ea3c..001b5656f8b 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.62.1 + 6.62.2-SNAPSHOT proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 086d1659b70..17f69574d51 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.1 + 6.62.2-SNAPSHOT proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 4dfae5bcd5c..274c9fcd7eb 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.62.1 + 6.62.2-SNAPSHOT diff --git a/versions.txt b/versions.txt index 8f703336abb..49d2f6914dc 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.1 -proto-google-cloud-spanner-v1:6.62.1:6.62.1 -proto-google-cloud-spanner-admin-database-v1:6.62.1:6.62.1 -grpc-google-cloud-spanner-v1:6.62.1:6.62.1 -grpc-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.1 -grpc-google-cloud-spanner-admin-database-v1:6.62.1:6.62.1 -google-cloud-spanner:6.62.1:6.62.1 -google-cloud-spanner-executor:6.62.1:6.62.1 -proto-google-cloud-spanner-executor-v1:6.62.1:6.62.1 -grpc-google-cloud-spanner-executor-v1:6.62.1:6.62.1 +proto-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.2-SNAPSHOT +proto-google-cloud-spanner-v1:6.62.1:6.62.2-SNAPSHOT +proto-google-cloud-spanner-admin-database-v1:6.62.1:6.62.2-SNAPSHOT +grpc-google-cloud-spanner-v1:6.62.1:6.62.2-SNAPSHOT +grpc-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.2-SNAPSHOT +grpc-google-cloud-spanner-admin-database-v1:6.62.1:6.62.2-SNAPSHOT +google-cloud-spanner:6.62.1:6.62.2-SNAPSHOT +google-cloud-spanner-executor:6.62.1:6.62.2-SNAPSHOT +proto-google-cloud-spanner-executor-v1:6.62.1:6.62.2-SNAPSHOT +grpc-google-cloud-spanner-executor-v1:6.62.1:6.62.2-SNAPSHOT From 7ae376acea4dce7a0bb4565d6c9bfdbbb75146c6 Mon Sep 17 00:00:00 2001 From: dengwe1 <159199800+dengwe1@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:53:46 -0700 Subject: [PATCH 2/7] feat: add support for transaction-level exclusion from change streams (#2959) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for transaction-level exclusion from change streams * cleanup * refactor: introduce PartitionedUpdateOption * Revert "refactor: introduce PartitionedUpdateOption" This reverts commit 96b508b50c633bfc58cc20c1b47649bf91ff68aa. * Add error handling in DML update APIs where excludeTxnFromChangeStreams option is not applicable * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- .../com/google/cloud/spanner/Options.java | 40 ++ .../spanner/PartitionedDmlTransaction.java | 8 +- .../com/google/cloud/spanner/SessionImpl.java | 25 +- .../cloud/spanner/TransactionRunnerImpl.java | 50 ++- .../cloud/spanner/DatabaseClientImplTest.java | 396 ++++++++++++++++++ .../com/google/cloud/spanner/OptionsTest.java | 38 ++ 6 files changed, 534 insertions(+), 23 deletions(-) diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java index d5c95d0a5a5..3dbd0c1cda3 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java @@ -61,6 +61,9 @@ public interface ReadOption {} public interface ReadQueryUpdateTransactionOption extends ReadOption, QueryOption, UpdateOption, TransactionOption {} + /** Marker interface to mark options applicable to Update and Write operations */ + public interface UpdateTransactionOption extends UpdateOption, TransactionOption {} + /** * Marker interface to mark options applicable to Create, Update and Delete operations in admin * API. @@ -108,6 +111,17 @@ public static TransactionOption commitStats() { public static TransactionOption optimisticLock() { return OPTIMISTIC_LOCK_OPTION; } + + /** + * Specifying this instructs the transaction to be excluded from being recorded in change streams + * with the DDL option `allow_txn_exclusion=true`. This does not exclude the transaction from + * being recorded in the change streams with the DDL option `allow_txn_exclusion` being false or + * unset. + */ + public static UpdateTransactionOption excludeTxnFromChangeStreams() { + return EXCLUDE_TXN_FROM_CHANGE_STREAMS_OPTION; + } + /** * Specifying this will cause the read to yield at most this many rows. This should be greater * than 0. @@ -281,6 +295,18 @@ void appendToOptions(Options options) { static final OptimisticLockOption OPTIMISTIC_LOCK_OPTION = new OptimisticLockOption(); + /** Option to request the transaction to be excluded from change streams. */ + static final class ExcludeTxnFromChangeStreamsOption extends InternalOption + implements UpdateTransactionOption { + @Override + void appendToOptions(Options options) { + options.withExcludeTxnFromChangeStreams = true; + } + } + + static final ExcludeTxnFromChangeStreamsOption EXCLUDE_TXN_FROM_CHANGE_STREAMS_OPTION = + new ExcludeTxnFromChangeStreamsOption(); + /** Option pertaining to flow control. */ static final class FlowControlOption extends InternalOption implements ReadAndQueryOption { final int prefetchChunks; @@ -405,6 +431,7 @@ void appendToOptions(Options options) { private String etag; private Boolean validateOnly; private Boolean withOptimisticLock; + private Boolean withExcludeTxnFromChangeStreams; private Boolean dataBoostEnabled; private DirectedReadOptions directedReadOptions; private DecodeMode decodeMode; @@ -508,6 +535,10 @@ Boolean withOptimisticLock() { return withOptimisticLock; } + Boolean withExcludeTxnFromChangeStreams() { + return withExcludeTxnFromChangeStreams; + } + boolean hasDataBoostEnabled() { return dataBoostEnabled != null; } @@ -571,6 +602,11 @@ public String toString() { if (withOptimisticLock != null) { b.append("withOptimisticLock: ").append(withOptimisticLock).append(' '); } + if (withExcludeTxnFromChangeStreams != null) { + b.append("withExcludeTxnFromChangeStreams: ") + .append(withExcludeTxnFromChangeStreams) + .append(' '); + } if (dataBoostEnabled != null) { b.append("dataBoostEnabled: ").append(dataBoostEnabled).append(' '); } @@ -616,6 +652,7 @@ public boolean equals(Object o) { && Objects.equals(etag(), that.etag()) && Objects.equals(validateOnly(), that.validateOnly()) && Objects.equals(withOptimisticLock(), that.withOptimisticLock()) + && Objects.equals(withExcludeTxnFromChangeStreams(), that.withExcludeTxnFromChangeStreams()) && Objects.equals(dataBoostEnabled(), that.dataBoostEnabled()) && Objects.equals(directedReadOptions(), that.directedReadOptions()); } @@ -662,6 +699,9 @@ public int hashCode() { if (withOptimisticLock != null) { result = 31 * result + withOptimisticLock.hashCode(); } + if (withExcludeTxnFromChangeStreams != null) { + result = 31 * result + withExcludeTxnFromChangeStreams.hashCode(); + } if (dataBoostEnabled != null) { result = 31 * result + dataBoostEnabled.hashCode(); } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/PartitionedDmlTransaction.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/PartitionedDmlTransaction.java index cabc270566c..d498bb232a1 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/PartitionedDmlTransaction.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/PartitionedDmlTransaction.java @@ -167,7 +167,7 @@ private ExecuteSqlRequest resumeOrRestartRequest( @VisibleForTesting ExecuteSqlRequest newTransactionRequestFrom(final Statement statement, final Options options) { - ByteString transactionId = initTransaction(); + ByteString transactionId = initTransaction(options); final TransactionSelector transactionSelector = TransactionSelector.newBuilder().setId(transactionId).build(); @@ -195,13 +195,15 @@ ExecuteSqlRequest newTransactionRequestFrom(final Statement statement, final Opt return builder.build(); } - private ByteString initTransaction() { + private ByteString initTransaction(final Options options) { final BeginTransactionRequest request = BeginTransactionRequest.newBuilder() .setSession(session.getName()) .setOptions( TransactionOptions.newBuilder() - .setPartitionedDml(TransactionOptions.PartitionedDml.getDefaultInstance())) + .setPartitionedDml(TransactionOptions.PartitionedDml.getDefaultInstance()) + .setExcludeTxnFromChangeStreams( + options.withExcludeTxnFromChangeStreams() == Boolean.TRUE)) .build(); Transaction tx = rpc.beginTransaction(request, session.getOptions(), true); if (tx.getId().isEmpty()) { diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java index bea44abab3e..8c4a0068599 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java @@ -69,11 +69,16 @@ static void throwIfTransactionsPending() { } static TransactionOptions createReadWriteTransactionOptions(Options options) { + TransactionOptions.Builder transactionOptions = TransactionOptions.newBuilder(); + if (options.withExcludeTxnFromChangeStreams() == Boolean.TRUE) { + transactionOptions.setExcludeTxnFromChangeStreams(true); + } TransactionOptions.ReadWrite.Builder readWrite = TransactionOptions.ReadWrite.newBuilder(); if (options.withOptimisticLock() == Boolean.TRUE) { readWrite.setReadLockMode(TransactionOptions.ReadWrite.ReadLockMode.OPTIMISTIC); } - return TransactionOptions.newBuilder().setReadWrite(readWrite).build(); + transactionOptions.setReadWrite(readWrite); + return transactionOptions.build(); } /** @@ -209,10 +214,16 @@ public CommitResponse writeAtLeastOnceWithOptions( CommitRequest.newBuilder() .setSession(name) .setReturnCommitStats(options.withCommitStats()) - .addAllMutations(mutationsProto) - .setSingleUseTransaction( - TransactionOptions.newBuilder() - .setReadWrite(TransactionOptions.ReadWrite.getDefaultInstance())); + .addAllMutations(mutationsProto); + + TransactionOptions.Builder transactionOptionsBuilder = + TransactionOptions.newBuilder() + .setReadWrite(TransactionOptions.ReadWrite.getDefaultInstance()); + if (options.withExcludeTxnFromChangeStreams() == Boolean.TRUE) { + transactionOptionsBuilder.setExcludeTxnFromChangeStreams(true); + } + requestBuilder.setSingleUseTransaction(transactionOptionsBuilder); + if (options.hasMaxCommitDelay()) { requestBuilder.setMaxCommitDelay( Duration.newBuilder() @@ -266,6 +277,10 @@ public ServerStream batchWriteAtLeastOnce( if (batchWriteRequestOptions != null) { requestBuilder.setRequestOptions(batchWriteRequestOptions); } + if (Options.fromTransactionOptions(transactionOptions).withExcludeTxnFromChangeStreams() + == Boolean.TRUE) { + requestBuilder.setExcludeTxnFromChangeStreams(true); + } ISpan span = tracer.spanBuilder(SpannerImpl.BATCH_WRITE); try (IScope s = tracer.withSpan(span)) { return spanner.getRpc().batchWriteAtLeastOnce(requestBuilder.build(), this.options); diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java index 3249be1bdb3..370d2f662f5 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java @@ -76,6 +76,10 @@ class TransactionRunnerImpl implements SessionTransaction, TransactionRunner { private static final String TRANSACTION_ALREADY_COMMITTED_MESSAGE = "Transaction has already committed"; + private static final String DML_INVALID_EXCLUDE_CHANGE_STREAMS_OPTION_MESSAGE = + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests. " + + "This option should be set at the transaction level."; + @VisibleForTesting static class TransactionContextImpl extends AbstractReadContext implements TransactionContext { @@ -371,7 +375,9 @@ public void run() { if (transactionId == null && transactionIdFuture == null) { requestBuilder.setSingleUseTransaction( TransactionOptions.newBuilder() - .setReadWrite(TransactionOptions.ReadWrite.getDefaultInstance())); + .setReadWrite(TransactionOptions.ReadWrite.getDefaultInstance()) + .setExcludeTxnFromChangeStreams( + options.withExcludeTxnFromChangeStreams() == Boolean.TRUE)); } else { requestBuilder.setTransactionId( transactionId == null @@ -725,14 +731,16 @@ public long executeUpdate(Statement statement, UpdateOption... options) { } private ResultSet internalExecuteUpdate( - Statement statement, QueryMode queryMode, UpdateOption... options) { + Statement statement, QueryMode queryMode, UpdateOption... updateOptions) { beforeReadOrQuery(); + final Options options = Options.fromUpdateOptions(updateOptions); + if (options.withExcludeTxnFromChangeStreams() != null) { + throw newSpannerException( + ErrorCode.INVALID_ARGUMENT, DML_INVALID_EXCLUDE_CHANGE_STREAMS_OPTION_MESSAGE); + } final ExecuteSqlRequest.Builder builder = getExecuteSqlRequestBuilder( - statement, - queryMode, - Options.fromUpdateOptions(options), - /* withTransactionSelector = */ true); + statement, queryMode, options, /* withTransactionSelector = */ true); try { com.google.spanner.v1.ResultSet resultSet = rpc.executeQuery(builder.build(), session.getOptions(), isRouteToLeader()); @@ -753,14 +761,16 @@ private ResultSet internalExecuteUpdate( } @Override - public ApiFuture executeUpdateAsync(Statement statement, UpdateOption... options) { + public ApiFuture executeUpdateAsync(Statement statement, UpdateOption... updateOptions) { beforeReadOrQuery(); + final Options options = Options.fromUpdateOptions(updateOptions); + if (options.withExcludeTxnFromChangeStreams() != null) { + throw newSpannerException( + ErrorCode.INVALID_ARGUMENT, DML_INVALID_EXCLUDE_CHANGE_STREAMS_OPTION_MESSAGE); + } final ExecuteSqlRequest.Builder builder = getExecuteSqlRequestBuilder( - statement, - QueryMode.NORMAL, - Options.fromUpdateOptions(options), - /* withTransactionSelector = */ true); + statement, QueryMode.NORMAL, options, /* withTransactionSelector = */ true); final ApiFuture resultSet; try { // Register the update as an async operation that must finish before the transaction may @@ -832,10 +842,15 @@ private SpannerException createAbortedExceptionForBatchDml(ExecuteBatchDmlRespon } @Override - public long[] batchUpdate(Iterable statements, UpdateOption... options) { + public long[] batchUpdate(Iterable statements, UpdateOption... updateOptions) { beforeReadOrQuery(); + final Options options = Options.fromUpdateOptions(updateOptions); + if (options.withExcludeTxnFromChangeStreams() != null) { + throw newSpannerException( + ErrorCode.INVALID_ARGUMENT, DML_INVALID_EXCLUDE_CHANGE_STREAMS_OPTION_MESSAGE); + } final ExecuteBatchDmlRequest.Builder builder = - getExecuteBatchDmlRequestBuilder(statements, Options.fromUpdateOptions(options)); + getExecuteBatchDmlRequestBuilder(statements, options); try { com.google.spanner.v1.ExecuteBatchDmlResponse response = rpc.executeBatchDml(builder.build(), session.getOptions()); @@ -869,10 +884,15 @@ public long[] batchUpdate(Iterable statements, UpdateOption... option @Override public ApiFuture batchUpdateAsync( - Iterable statements, UpdateOption... options) { + Iterable statements, UpdateOption... updateOptions) { beforeReadOrQuery(); + final Options options = Options.fromUpdateOptions(updateOptions); + if (options.withExcludeTxnFromChangeStreams() != null) { + throw newSpannerException( + ErrorCode.INVALID_ARGUMENT, DML_INVALID_EXCLUDE_CHANGE_STREAMS_OPTION_MESSAGE); + } final ExecuteBatchDmlRequest.Builder builder = - getExecuteBatchDmlRequestBuilder(statements, Options.fromUpdateOptions(options)); + getExecuteBatchDmlRequestBuilder(statements, options); ApiFuture response; try { // Register the update as an async operation that must finish before the transaction may diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index 7cba80edd8d..4ab6829a327 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -75,6 +75,7 @@ import com.google.rpc.RetryInfo; import com.google.spanner.v1.BatchWriteRequest; import com.google.spanner.v1.BatchWriteResponse; +import com.google.spanner.v1.BeginTransactionRequest; import com.google.spanner.v1.CommitRequest; import com.google.spanner.v1.DeleteSessionRequest; import com.google.spanner.v1.DirectedReadOptions; @@ -1334,6 +1335,14 @@ public void testWrite() { Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build())); assertNotNull(timestamp); + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List commitRequests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(commitRequests).hasSize(1); CommitRequest commit = commitRequests.get(0); @@ -1388,6 +1397,14 @@ public void testWriteWithOptions() { Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), Options.priority(RpcPriority.HIGH)); + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List commits = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(commits).hasSize(1); CommitRequest commit = commits.get(0); @@ -1409,6 +1426,24 @@ public void testWriteWithCommitStats() { assertNotNull(response.getCommitStats()); } + @Test + public void testWriteWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + client.writeWithOptions( + Collections.singletonList( + Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), + Options.excludeTxnFromChangeStreams()); + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + @Test public void testWriteAtLeastOnce() { DatabaseClient client = @@ -1418,6 +1453,15 @@ public void testWriteAtLeastOnce() { Collections.singletonList( Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build())); assertNotNull(timestamp); + + List commitRequests = mockSpanner.getRequestsOfType(CommitRequest.class); + assertThat(commitRequests).hasSize(1); + CommitRequest commit = commitRequests.get(0); + assertNotNull(commit.getSingleUseTransaction()); + assertTrue(commit.getSingleUseTransaction().hasReadWrite()); + assertFalse(commit.getSingleUseTransaction().getExcludeTxnFromChangeStreams()); + assertNotNull(commit.getRequestOptions()); + assertEquals(Priority.PRIORITY_UNSPECIFIED, commit.getRequestOptions().getPriority()); } @Test @@ -1438,6 +1482,7 @@ public void testWriteAtLeastOnceWithCommitStats() { CommitRequest commit = commitRequests.get(0); assertNotNull(commit.getSingleUseTransaction()); assertTrue(commit.getSingleUseTransaction().hasReadWrite()); + assertFalse(commit.getSingleUseTransaction().getExcludeTxnFromChangeStreams()); assertNotNull(commit.getRequestOptions()); assertEquals(Priority.PRIORITY_UNSPECIFIED, commit.getRequestOptions().getPriority()); } @@ -1456,6 +1501,7 @@ public void testWriteAtLeastOnceWithOptions() { CommitRequest commit = commitRequests.get(0); assertNotNull(commit.getSingleUseTransaction()); assertTrue(commit.getSingleUseTransaction().hasReadWrite()); + assertFalse(commit.getSingleUseTransaction().getExcludeTxnFromChangeStreams()); assertNotNull(commit.getRequestOptions()); assertEquals(Priority.PRIORITY_LOW, commit.getRequestOptions().getPriority()); } @@ -1474,11 +1520,29 @@ public void testWriteAtLeastOnceWithTagOptions() { CommitRequest commit = commitRequests.get(0); assertNotNull(commit.getSingleUseTransaction()); assertTrue(commit.getSingleUseTransaction().hasReadWrite()); + assertFalse(commit.getSingleUseTransaction().getExcludeTxnFromChangeStreams()); assertNotNull(commit.getRequestOptions()); assertThat(commit.getRequestOptions().getTransactionTag()).isEqualTo("app=spanner,env=test"); assertThat(commit.getRequestOptions().getRequestTag()).isEmpty(); } + @Test + public void testWriteAtLeastOnceWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + client.writeAtLeastOnceWithOptions( + Collections.singletonList( + Mutation.newInsertBuilder("FOO").set("ID").to(1L).set("NAME").to("Bar").build()), + Options.excludeTxnFromChangeStreams()); + + List commitRequests = mockSpanner.getRequestsOfType(CommitRequest.class); + assertThat(commitRequests).hasSize(1); + CommitRequest commit = commitRequests.get(0); + assertNotNull(commit.getSingleUseTransaction()); + assertTrue(commit.getSingleUseTransaction().hasReadWrite()); + assertTrue(commit.getSingleUseTransaction().getExcludeTxnFromChangeStreams()); + } + @Test public void testBatchWriteAtLeastOnceWithoutOptions() { DatabaseClient client = @@ -1500,6 +1564,7 @@ public void testBatchWriteAtLeastOnceWithoutOptions() { BatchWriteRequest request = requests.get(0); assertEquals(request.getMutationGroupsCount(), 4); assertEquals(request.getRequestOptions().getPriority(), Priority.PRIORITY_UNSPECIFIED); + assertFalse(request.getExcludeTxnFromChangeStreams()); } @Test @@ -1514,6 +1579,7 @@ public void testBatchWriteAtLeastOnceWithOptions() { BatchWriteRequest request = requests.get(0); assertEquals(request.getMutationGroupsCount(), 4); assertEquals(request.getRequestOptions().getPriority(), Priority.PRIORITY_LOW); + assertFalse(request.getExcludeTxnFromChangeStreams()); } @Test @@ -1529,6 +1595,21 @@ public void testBatchWriteAtLeastOnceWithTagOptions() { assertEquals(request.getMutationGroupsCount(), 4); assertEquals(request.getRequestOptions().getTransactionTag(), "app=spanner,env=test"); assertThat(request.getRequestOptions().getRequestTag()).isEmpty(); + assertFalse(request.getExcludeTxnFromChangeStreams()); + } + + @Test + public void testBatchWriteAtLeastOnceWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + consumeBatchWriteStream( + client.batchWriteAtLeastOnce(MUTATION_GROUPS, Options.excludeTxnFromChangeStreams())); + + List requests = mockSpanner.getRequestsOfType(BatchWriteRequest.class); + assertEquals(requests.size(), 1); + BatchWriteRequest request = requests.get(0); + assertEquals(request.getMutationGroupsCount(), 4); + assertTrue(request.getExcludeTxnFromChangeStreams()); } @Test @@ -1782,6 +1863,9 @@ public void testExecuteUpdateWithTag() { assertThat(request.getRequestOptions().getRequestTag()) .isEqualTo("app=spanner,env=test,action=update"); assertThat(request.getRequestOptions().getTransactionTag()).isEmpty(); + assertNotNull(request.getTransaction().getBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertFalse(request.getTransaction().getBegin().getExcludeTxnFromChangeStreams()); } @Test @@ -1805,6 +1889,9 @@ public void testBatchUpdateWithTag() { .isEqualTo("app=spanner,env=test,action=batch"); assertThat(request.getRequestOptions().getTransactionTag()) .isEqualTo("app=spanner,env=test,action=txn"); + assertNotNull(request.getTransaction().getBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertFalse(request.getTransaction().getBegin().getExcludeTxnFromChangeStreams()); } @Test @@ -1814,6 +1901,14 @@ public void testPartitionedDMLWithTag() { client.executePartitionedUpdate( UPDATE_STATEMENT, Options.tag("app=spanner,env=test,action=dml")); + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasPartitionedDml()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); assertThat(requests).hasSize(1); ExecuteSqlRequest request = requests.get(0); @@ -1835,6 +1930,14 @@ public void testCommitWithTag() { return null; }); + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); CommitRequest request = requests.get(0); @@ -1855,6 +1958,14 @@ public void testTransactionManagerCommitWithTag() { manager.commit(); } + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); CommitRequest request = requests.get(0); @@ -1877,6 +1988,14 @@ public void testAsyncRunnerCommitWithTag() { }, executor)); + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); CommitRequest request = requests.get(0); @@ -1904,6 +2023,14 @@ public void testAsyncTransactionManagerCommitWithTag() { .commitAsync()); } + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertFalse(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + List requests = mockSpanner.getRequestsOfType(CommitRequest.class); assertThat(requests).hasSize(1); CommitRequest request = requests.get(0); @@ -1913,6 +2040,275 @@ public void testAsyncTransactionManagerCommitWithTag() { .isEqualTo("app=spanner,env=test,action=manager"); } + @Test + public void testReadWriteTxnWithExcludeTxnFromChangeStreams_executeUpdate() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(Options.excludeTxnFromChangeStreams()); + runner.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)); + + List requests = mockSpanner.getRequestsOfType(ExecuteSqlRequest.class); + assertThat(requests).hasSize(1); + ExecuteSqlRequest request = requests.get(0); + assertNotNull(request.getTransaction().getBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getTransaction().getBegin().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testReadWriteTxnWithExcludeTxnFromChangeStreams_batchUpdate() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(Options.excludeTxnFromChangeStreams()); + runner.run(transaction -> transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT))); + + List requests = + mockSpanner.getRequestsOfType(ExecuteBatchDmlRequest.class); + assertThat(requests).hasSize(1); + ExecuteBatchDmlRequest request = requests.get(0); + assertNotNull(request.getTransaction().getBegin()); + assertTrue(request.getTransaction().getBegin().hasReadWrite()); + assertTrue(request.getTransaction().getBegin().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testPartitionedDMLWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + client.executePartitionedUpdate(UPDATE_STATEMENT, Options.excludeTxnFromChangeStreams()); + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasPartitionedDml()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testCommitWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(Options.excludeTxnFromChangeStreams()); + runner.run( + transaction -> { + transaction.buffer(Mutation.delete("TEST", KeySet.all())); + return null; + }); + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testTransactionManagerCommitWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + try (TransactionManager manager = + client.transactionManager(Options.excludeTxnFromChangeStreams())) { + TransactionContext transaction = manager.begin(); + transaction.buffer(Mutation.delete("TEST", KeySet.all())); + manager.commit(); + } + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testAsyncRunnerCommitWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + AsyncRunner runner = client.runAsync(Options.excludeTxnFromChangeStreams()); + get( + runner.runAsync( + txn -> { + txn.buffer(Mutation.delete("TEST", KeySet.all())); + return ApiFutures.immediateFuture(null); + }, + executor)); + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testAsyncTransactionManagerCommitWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + try (AsyncTransactionManager manager = + client.transactionManagerAsync(Options.excludeTxnFromChangeStreams())) { + TransactionContextFuture transaction = manager.beginAsync(); + get( + transaction + .then( + (txn, input) -> { + txn.buffer(Mutation.delete("TEST", KeySet.all())); + return ApiFutures.immediateFuture(null); + }, + executor) + .commitAsync()); + } + + List beginTransactions = + mockSpanner.getRequestsOfType(BeginTransactionRequest.class); + assertThat(beginTransactions).hasSize(1); + BeginTransactionRequest beginTransaction = beginTransactions.get(0); + assertNotNull(beginTransaction.getOptions()); + assertTrue(beginTransaction.getOptions().hasReadWrite()); + assertTrue(beginTransaction.getOptions().getExcludeTxnFromChangeStreams()); + } + + @Test + public void testExecuteUpdateWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + runner.run( + transaction -> + transaction.executeUpdate( + UPDATE_STATEMENT, Options.excludeTxnFromChangeStreams()))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + + @Test + public void testExecuteUpdateAsyncWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + AsyncRunner runner = client.runAsync(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + get( + runner.runAsync( + txn -> { + txn.executeUpdateAsync( + UPDATE_STATEMENT, Options.excludeTxnFromChangeStreams()); + return ApiFutures.immediateFuture(null); + }, + executor))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + + @Test + public void testAnalyzeUpdateWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + runner.run( + transaction -> + transaction.analyzeUpdate( + UPDATE_STATEMENT, + QueryAnalyzeMode.PROFILE, + Options.excludeTxnFromChangeStreams()))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + + @Test + public void testAnalyzeUpdateStatementWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + runner.run( + transaction -> + transaction.analyzeUpdateStatement( + UPDATE_STATEMENT, + QueryAnalyzeMode.PROFILE, + Options.excludeTxnFromChangeStreams()))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + + @Test + public void testBatchUpdateWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + TransactionRunner runner = client.readWriteTransaction(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + runner.run( + transaction -> + transaction.batchUpdate( + Collections.singletonList(UPDATE_STATEMENT), + Options.excludeTxnFromChangeStreams()))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + + @Test + public void testBatchUpdateAsyncWithExcludeTxnFromChangeStreams() { + DatabaseClient client = + spanner.getDatabaseClient(DatabaseId.of(TEST_PROJECT, TEST_INSTANCE, TEST_DATABASE)); + AsyncRunner runner = client.runAsync(); + SpannerException e = + assertThrows( + SpannerException.class, + () -> + get( + runner.runAsync( + txn -> { + txn.batchUpdateAsync( + Collections.singletonList(UPDATE_STATEMENT), + Options.excludeTxnFromChangeStreams()); + return ApiFutures.immediateFuture(null); + }, + executor))); + assertThat(e.getErrorCode()).isEqualTo(ErrorCode.INVALID_ARGUMENT); + assertThat(e.getMessage()) + .contains( + "Options.excludeTxnFromChangeStreams() cannot be specified for individual DML requests." + + " This option should be set at the transaction level."); + } + @Test public void singleUse() { DatabaseClientImpl client = diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java index e0bbf81f297..8c9a5d957e8 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -100,6 +101,7 @@ public void allOptionsAbsent() { assertThat(options.hasTag()).isFalse(); assertThat(options.hasDataBoostEnabled()).isFalse(); assertThat(options.hasDirectedReadOptions()).isFalse(); + assertNull(options.withExcludeTxnFromChangeStreams()); assertThat(options.toString()).isEqualTo(""); assertThat(options.equals(options)).isTrue(); assertThat(options.equals(null)).isFalse(); @@ -691,4 +693,40 @@ public void directedReadHashCode() { public void directedReadsNullNotAllowed() { assertThrows(NullPointerException.class, () -> Options.directedRead(null)); } + + @Test + public void transactionOptionsExcludeTxnFromChangeStreams() { + Options option1 = Options.fromTransactionOptions(Options.excludeTxnFromChangeStreams()); + Options option2 = Options.fromTransactionOptions(Options.excludeTxnFromChangeStreams()); + Options option3 = Options.fromTransactionOptions(); + + assertEquals(option1, option2); + assertEquals(option1.hashCode(), option2.hashCode()); + assertNotEquals(option1, option3); + assertNotEquals(option1.hashCode(), option3.hashCode()); + + assertTrue(option1.withExcludeTxnFromChangeStreams()); + assertThat(option1.toString()).contains("withExcludeTxnFromChangeStreams: true"); + + assertNull(option3.withExcludeTxnFromChangeStreams()); + assertThat(option3.toString()).doesNotContain("withExcludeTxnFromChangeStreams: true"); + } + + @Test + public void updateOptionsExcludeTxnFromChangeStreams() { + Options option1 = Options.fromUpdateOptions(Options.excludeTxnFromChangeStreams()); + Options option2 = Options.fromUpdateOptions(Options.excludeTxnFromChangeStreams()); + Options option3 = Options.fromUpdateOptions(); + + assertEquals(option1, option2); + assertEquals(option1.hashCode(), option2.hashCode()); + assertNotEquals(option1, option3); + assertNotEquals(option1.hashCode(), option3.hashCode()); + + assertTrue(option1.withExcludeTxnFromChangeStreams()); + assertThat(option1.toString()).contains("withExcludeTxnFromChangeStreams: true"); + + assertNull(option3.withExcludeTxnFromChangeStreams()); + assertThat(option3.toString()).doesNotContain("withExcludeTxnFromChangeStreams: true"); + } } From cf116412d46c5047167d4dd60ef9c88c3d9c754b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 29 Mar 2024 05:39:38 +0100 Subject: [PATCH 3/7] deps: update dependency com.google.cloud:google-cloud-trace to v2.39.0 (#2988) --- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 7cb098895e1..5c6618ee6b4 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -23,7 +23,7 @@ 1.8 UTF-8 0.31.1 - 2.38.0 + 2.39.0 3.39.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 274c9fcd7eb..bc38ecae8b0 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -23,7 +23,7 @@ 1.8 UTF-8 0.31.1 - 2.38.0 + 2.39.0 3.39.0 From 46972619f88018bad1b4e05526a618d38e2e0897 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 29 Mar 2024 05:40:42 +0100 Subject: [PATCH 4/7] deps: update dependency commons-io:commons-io to v2.16.0 (#2986) --- google-cloud-spanner-executor/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index f163b67618f..5635c3a0ab1 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -134,7 +134,7 @@ commons-io commons-io - 2.15.1 + 2.16.0 From 0a1ffcb371bdee6e478e3aa53b0a4591055134e3 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 30 Mar 2024 04:18:38 +0100 Subject: [PATCH 5/7] deps: update dependency com.google.cloud:google-cloud-monitoring to v3.40.0 (#2987) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * deps: update dependency com.google.cloud:google-cloud-monitoring to v3.40.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- README.md | 2 +- samples/install-without-bom/pom.xml | 2 +- samples/snapshot/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 56d91c89705..df14a2fb3a5 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.34.0') +implementation platform('com.google.cloud:libraries-bom:26.35.0') implementation 'com.google.cloud:google-cloud-spanner' ``` diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 5c6618ee6b4..b3647430cac 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -24,7 +24,7 @@ UTF-8 0.31.1 2.39.0 - 3.39.0 + 3.40.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index bc38ecae8b0..85c21ea8e64 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -24,7 +24,7 @@ UTF-8 0.31.1 2.39.0 - 3.39.0 + 3.40.0 From 60c86bf615ee96dcf8a86a8847449c17ecd2579a Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 30 Mar 2024 04:19:07 +0100 Subject: [PATCH 6/7] chore(deps): update dependency com.google.cloud:libraries-bom to v26.35.0 (#2989) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update dependency com.google.cloud:libraries-bom to v26.35.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot --- README.md | 2 +- samples/native-image/pom.xml | 2 +- samples/snippets/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index df14a2fb3a5..723b796a9e6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file: com.google.cloud libraries-bom - 26.34.0 + 26.35.0 pom import diff --git a/samples/native-image/pom.xml b/samples/native-image/pom.xml index b009be4637d..c40930a15a8 100644 --- a/samples/native-image/pom.xml +++ b/samples/native-image/pom.xml @@ -29,7 +29,7 @@ com.google.cloud libraries-bom - 26.34.0 + 26.35.0 pom import diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index 655c9195864..1698a1207aa 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -34,7 +34,7 @@ com.google.cloud libraries-bom - 26.34.0 + 26.35.0 pom import From 094f5defc64033d416c6bd16ca224e017cc1329f Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Sat, 30 Mar 2024 10:22:03 +0530 Subject: [PATCH 7/7] chore(main): release 6.63.0 (#2985) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 14 +++++++++++++ google-cloud-spanner-bom/pom.xml | 18 ++++++++--------- google-cloud-spanner-executor/pom.xml | 4 ++-- google-cloud-spanner/pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- grpc-google-cloud-spanner-executor-v1/pom.xml | 4 ++-- grpc-google-cloud-spanner-v1/pom.xml | 4 ++-- pom.xml | 20 +++++++++---------- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- .../pom.xml | 4 ++-- proto-google-cloud-spanner-v1/pom.xml | 4 ++-- samples/snapshot/pom.xml | 2 +- versions.txt | 20 +++++++++---------- 15 files changed, 64 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee3da44d653..b43cabe3b12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [6.63.0](https://github.com/googleapis/java-spanner/compare/v6.62.1...v6.63.0) (2024-03-30) + + +### Features + +* Add support for transaction-level exclusion from change streams ([#2959](https://github.com/googleapis/java-spanner/issues/2959)) ([7ae376a](https://github.com/googleapis/java-spanner/commit/7ae376acea4dce7a0bb4565d6c9bfdbbb75146c6)) + + +### Dependencies + +* Update dependency com.google.cloud:google-cloud-monitoring to v3.40.0 ([#2987](https://github.com/googleapis/java-spanner/issues/2987)) ([0a1ffcb](https://github.com/googleapis/java-spanner/commit/0a1ffcb371bdee6e478e3aa53b0a4591055134e3)) +* Update dependency com.google.cloud:google-cloud-trace to v2.39.0 ([#2988](https://github.com/googleapis/java-spanner/issues/2988)) ([cf11641](https://github.com/googleapis/java-spanner/commit/cf116412d46c5047167d4dd60ef9c88c3d9c754b)) +* Update dependency commons-io:commons-io to v2.16.0 ([#2986](https://github.com/googleapis/java-spanner/issues/2986)) ([4697261](https://github.com/googleapis/java-spanner/commit/46972619f88018bad1b4e05526a618d38e2e0897)) + ## [6.62.1](https://github.com/googleapis/java-spanner/compare/v6.62.0...v6.62.1) (2024-03-28) diff --git a/google-cloud-spanner-bom/pom.xml b/google-cloud-spanner-bom/pom.xml index 18e1b8680e5..0e156cdde0d 100644 --- a/google-cloud-spanner-bom/pom.xml +++ b/google-cloud-spanner-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner-bom - 6.62.2-SNAPSHOT + 6.63.0 pom com.google.cloud @@ -53,43 +53,43 @@ com.google.cloud google-cloud-spanner - 6.62.2-SNAPSHOT + 6.63.0 com.google.cloud google-cloud-spanner test-jar - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/google-cloud-spanner-executor/pom.xml b/google-cloud-spanner-executor/pom.xml index 5635c3a0ab1..64b606e5a96 100644 --- a/google-cloud-spanner-executor/pom.xml +++ b/google-cloud-spanner-executor/pom.xml @@ -5,14 +5,14 @@ 4.0.0 com.google.cloud google-cloud-spanner-executor - 6.62.2-SNAPSHOT + 6.63.0 jar Google Cloud Spanner Executor com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml index b9102aef691..d471f46ae17 100644 --- a/google-cloud-spanner/pom.xml +++ b/google-cloud-spanner/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-spanner - 6.62.2-SNAPSHOT + 6.63.0 jar Google Cloud Spanner https://github.com/googleapis/java-spanner @@ -11,7 +11,7 @@ com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 google-cloud-spanner diff --git a/grpc-google-cloud-spanner-admin-database-v1/pom.xml b/grpc-google-cloud-spanner-admin-database-v1/pom.xml index 45e2e4ef867..5c1af8f41b9 100644 --- a/grpc-google-cloud-spanner-admin-database-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 grpc-google-cloud-spanner-admin-database-v1 GRPC library for grpc-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml index 3823c47d795..17fb51703b8 100644 --- a/grpc-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/grpc-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 grpc-google-cloud-spanner-admin-instance-v1 GRPC library for grpc-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/grpc-google-cloud-spanner-executor-v1/pom.xml b/grpc-google-cloud-spanner-executor-v1/pom.xml index 559607c04c2..8f2a3b37db1 100644 --- a/grpc-google-cloud-spanner-executor-v1/pom.xml +++ b/grpc-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.62.2-SNAPSHOT + 6.63.0 grpc-google-cloud-spanner-executor-v1 GRPC library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/grpc-google-cloud-spanner-v1/pom.xml b/grpc-google-cloud-spanner-v1/pom.xml index ada78070399..892eaa734c9 100644 --- a/grpc-google-cloud-spanner-v1/pom.xml +++ b/grpc-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 grpc-google-cloud-spanner-v1 GRPC library for grpc-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/pom.xml b/pom.xml index 0e51c1f2cf4..cf1115a93fa 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-spanner-parent pom - 6.62.2-SNAPSHOT + 6.63.0 Google Cloud Spanner Parent https://github.com/googleapis/java-spanner @@ -61,47 +61,47 @@ com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-executor-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.api.grpc grpc-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 com.google.cloud google-cloud-spanner - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/proto-google-cloud-spanner-admin-database-v1/pom.xml b/proto-google-cloud-spanner-admin-database-v1/pom.xml index 2e9cca5344a..d434fe8202c 100644 --- a/proto-google-cloud-spanner-admin-database-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-database-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-database-v1 - 6.62.2-SNAPSHOT + 6.63.0 proto-google-cloud-spanner-admin-database-v1 PROTO library for proto-google-cloud-spanner-admin-database-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/proto-google-cloud-spanner-admin-instance-v1/pom.xml b/proto-google-cloud-spanner-admin-instance-v1/pom.xml index e8bd6a96863..0ea8a45b2d7 100644 --- a/proto-google-cloud-spanner-admin-instance-v1/pom.xml +++ b/proto-google-cloud-spanner-admin-instance-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-admin-instance-v1 - 6.62.2-SNAPSHOT + 6.63.0 proto-google-cloud-spanner-admin-instance-v1 PROTO library for proto-google-cloud-spanner-admin-instance-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/proto-google-cloud-spanner-executor-v1/pom.xml b/proto-google-cloud-spanner-executor-v1/pom.xml index 001b5656f8b..24c5fac07b1 100644 --- a/proto-google-cloud-spanner-executor-v1/pom.xml +++ b/proto-google-cloud-spanner-executor-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-executor-v1 - 6.62.2-SNAPSHOT + 6.63.0 proto-google-cloud-spanner-executor-v1 Proto library for google-cloud-spanner com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/proto-google-cloud-spanner-v1/pom.xml b/proto-google-cloud-spanner-v1/pom.xml index 17f69574d51..ceb0c5bf614 100644 --- a/proto-google-cloud-spanner-v1/pom.xml +++ b/proto-google-cloud-spanner-v1/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-spanner-v1 - 6.62.2-SNAPSHOT + 6.63.0 proto-google-cloud-spanner-v1 PROTO library for proto-google-cloud-spanner-v1 com.google.cloud google-cloud-spanner-parent - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 85c21ea8e64..cb8ad86b626 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -32,7 +32,7 @@ com.google.cloud google-cloud-spanner - 6.62.2-SNAPSHOT + 6.63.0 diff --git a/versions.txt b/versions.txt index 49d2f6914dc..35f3118a473 100644 --- a/versions.txt +++ b/versions.txt @@ -1,13 +1,13 @@ # Format: # module:released-version:current-version -proto-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.2-SNAPSHOT -proto-google-cloud-spanner-v1:6.62.1:6.62.2-SNAPSHOT -proto-google-cloud-spanner-admin-database-v1:6.62.1:6.62.2-SNAPSHOT -grpc-google-cloud-spanner-v1:6.62.1:6.62.2-SNAPSHOT -grpc-google-cloud-spanner-admin-instance-v1:6.62.1:6.62.2-SNAPSHOT -grpc-google-cloud-spanner-admin-database-v1:6.62.1:6.62.2-SNAPSHOT -google-cloud-spanner:6.62.1:6.62.2-SNAPSHOT -google-cloud-spanner-executor:6.62.1:6.62.2-SNAPSHOT -proto-google-cloud-spanner-executor-v1:6.62.1:6.62.2-SNAPSHOT -grpc-google-cloud-spanner-executor-v1:6.62.1:6.62.2-SNAPSHOT +proto-google-cloud-spanner-admin-instance-v1:6.63.0:6.63.0 +proto-google-cloud-spanner-v1:6.63.0:6.63.0 +proto-google-cloud-spanner-admin-database-v1:6.63.0:6.63.0 +grpc-google-cloud-spanner-v1:6.63.0:6.63.0 +grpc-google-cloud-spanner-admin-instance-v1:6.63.0:6.63.0 +grpc-google-cloud-spanner-admin-database-v1:6.63.0:6.63.0 +google-cloud-spanner:6.63.0:6.63.0 +google-cloud-spanner-executor:6.63.0:6.63.0 +proto-google-cloud-spanner-executor-v1:6.63.0:6.63.0 +grpc-google-cloud-spanner-executor-v1:6.63.0:6.63.0