This method has the same behavior as {@link #executePartitionedUpdate(Statement,
- * UpdateOption...)} but allows specifying a transaction tag that will be applied to all
- * partitioned operations.
- *
- * @param stmt The Partitioned DML statement to execute
- * @param transactionTag The transaction tag to apply to all partitioned operations. The tag must
- * be a printable string (ASCII 32-126) with maximum length of 50 characters.
- * @param options The options to use for the update operation
- * @return The total number of rows modified by the statement
- * @throws SpannerException if the operation failed
- */
- long executePartitionedUpdate(
- Statement stmt, @Nullable String transactionTag, UpdateOption... options);
}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java
index 9200aa23a2..d7f16f8952 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseClientImpl.java
@@ -309,21 +309,9 @@ public AsyncTransactionManager transactionManagerAsync(TransactionOption... opti
@Override
public long executePartitionedUpdate(final Statement stmt, final UpdateOption... options) {
- return executePartitionedUpdateWithOptions(stmt, null, options);
- }
-
- @Override
- public long executePartitionedUpdate(
- final Statement stmt, @Nullable String transactionTag, final UpdateOption... options) {
- return executePartitionedUpdateWithOptions(stmt, transactionTag, options);
- }
-
- private long executePartitionedUpdateWithOptions(
- final Statement stmt, @Nullable String transactionTag, final UpdateOption... options) {
ISpan span = tracer.spanBuilder(PARTITION_DML_TRANSACTION);
try (IScope s = tracer.withSpan(span)) {
- return runWithSessionRetry(
- session -> session.executePartitionedUpdate(stmt, transactionTag, options));
+ return runWithSessionRetry(session -> session.executePartitionedUpdate(stmt, options));
} catch (RuntimeException e) {
span.setStatus(e);
span.end();
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 9c3257586f..73c47a32ac 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
@@ -197,6 +197,10 @@ public static ReadQueryUpdateTransactionOption tag(String name) {
return new TagOption(name);
}
+ public static ReadQueryUpdateTransactionOption transactionTag(String name) {
+ return new TransactionTagOption(name);
+ }
+
/**
* Specifying this will cause the list operations to fetch at most this many records in a page.
*/
@@ -394,6 +398,24 @@ void appendToOptions(Options options) {
}
}
+ static final class TransactionTagOption extends InternalOption
+ implements ReadQueryUpdateTransactionOption {
+ private final String transactionTag;
+
+ TransactionTagOption(String transactionTag) {
+ this.transactionTag = transactionTag;
+ }
+
+ String getTransactionTag() {
+ return transactionTag;
+ }
+
+ @Override
+ void appendToOptions(Options options) {
+ options.transactionTag = transactionTag;
+ }
+ }
+
static final class EtagOption extends InternalOption implements DeleteAdminApiOption {
private final String etag;
@@ -462,6 +484,7 @@ void appendToOptions(Options options) {
private RpcPriority priority;
private String tag;
private String etag;
+ private String transactionTag;
private Boolean validateOnly;
private Boolean withOptimisticLock;
private Boolean withExcludeTxnFromChangeStreams;
@@ -545,6 +568,14 @@ boolean hasTag() {
return tag != null;
}
+ boolean hasTransactionTag() {
+ return transactionTag != null;
+ }
+
+ String transactionTag() {
+ return transactionTag;
+ }
+
String tag() {
return tag;
}
@@ -661,6 +692,9 @@ public String toString() {
if (orderBy != null) {
b.append("orderBy: ").append(orderBy).append(' ');
}
+ if (transactionTag != null) {
+ b.append("transactionTag: ").append(transactionTag).append(' ');
+ }
return b.toString();
}
@@ -694,6 +728,7 @@ public boolean equals(Object o) {
&& Objects.equals(filter(), that.filter())
&& Objects.equals(priority(), that.priority())
&& Objects.equals(tag(), that.tag())
+ && Objects.equals(transactionTag, that.transactionTag)
&& Objects.equals(etag(), that.etag())
&& Objects.equals(validateOnly(), that.validateOnly())
&& Objects.equals(withOptimisticLock(), that.withOptimisticLock())
@@ -760,6 +795,9 @@ public int hashCode() {
if (orderBy != null) {
result = 31 * result + orderBy.hashCode();
}
+ if (transactionTag != null) {
+ result = 31 * result + transactionTag.hashCode();
+ }
return result;
}
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 dc4d1f54f3..cabfd2c476 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
@@ -43,7 +43,6 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.annotation.Nullable;
import org.threeten.bp.Duration;
import org.threeten.bp.temporal.ChronoUnit;
@@ -55,16 +54,13 @@ public class PartitionedDmlTransaction implements SessionImpl.SessionTransaction
private final SessionImpl session;
private final SpannerRpc rpc;
private final Ticker ticker;
- private final @Nullable String transactionTag;
private final IsRetryableInternalError isRetryableInternalErrorPredicate;
private volatile boolean isValid = true;
- PartitionedDmlTransaction(
- SessionImpl session, SpannerRpc rpc, Ticker ticker, @Nullable String transactionTag) {
+ PartitionedDmlTransaction(SessionImpl session, SpannerRpc rpc, Ticker ticker) {
this.session = session;
this.rpc = rpc;
this.ticker = ticker;
- this.transactionTag = transactionTag;
this.isRetryableInternalErrorPredicate = new IsRetryableInternalError();
}
@@ -198,8 +194,8 @@ ExecuteSqlRequest newTransactionRequestFrom(final Statement statement, final Opt
if (options.hasTag()) {
requestOptionsBuilder.setRequestTag(options.tag());
}
- if (transactionTag != null) {
- requestOptionsBuilder.setTransactionTag(transactionTag);
+ if (options.hasTransactionTag()) {
+ requestOptionsBuilder.setTransactionTag(options.transactionTag());
}
builder.setRequestOptions(requestOptionsBuilder.build());
}
@@ -216,9 +212,9 @@ private ByteString initTransaction(final Options options) {
.setExcludeTxnFromChangeStreams(
options.withExcludeTxnFromChangeStreams() == Boolean.TRUE));
- if (transactionTag != null) {
+ if (options.hasTransactionTag()) {
builder.setRequestOptions(
- RequestOptions.newBuilder().setTransactionTag(transactionTag).build());
+ RequestOptions.newBuilder().setTransactionTag(options.transactionTag()).build());
}
Transaction tx = rpc.beginTransaction(builder.build(), 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 f0eca14fee..5bd3160368 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
@@ -201,18 +201,7 @@ public DatabaseId getDatabaseId() {
public long executePartitionedUpdate(Statement stmt, UpdateOption... options) {
setActive(null);
PartitionedDmlTransaction txn =
- new PartitionedDmlTransaction(this, spanner.getRpc(), Ticker.systemTicker(), null);
- return txn.executeStreamingPartitionedUpdate(
- stmt, spanner.getOptions().getPartitionedDmlTimeout(), options);
- }
-
- @Override
- public long executePartitionedUpdate(
- Statement stmt, @Nullable String transactionTag, UpdateOption... options) {
- setActive(null);
- PartitionedDmlTransaction txn =
- new PartitionedDmlTransaction(
- this, spanner.getRpc(), Ticker.systemTicker(), transactionTag);
+ new PartitionedDmlTransaction(this, spanner.getRpc(), Ticker.systemTicker());
return txn.executeStreamingPartitionedUpdate(
stmt, spanner.getOptions().getPartitionedDmlTimeout(), options);
}
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java
index d621f91d63..cf50fa44c7 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java
@@ -1273,11 +1273,6 @@ default AsyncTransactionManager transactionManagerAsync(TransactionOption... opt
default long executePartitionedUpdate(Statement stmt, UpdateOption... options) {
return get().executePartitionedUpdate(stmt, options);
}
-
- default long executePartitionedUpdate(
- Statement stmt, @Nullable String transactionTag, UpdateOption... options) {
- return get().executePartitionedUpdate(stmt, transactionTag, options);
- }
}
class PooledSessionFutureWrapper implements SessionFutureWrapper