public class DatabaseClientWithChangeSets extends Object implements com.google.cloud.spanner.DatabaseClient
DatabaseClient that automatically generates change set id's and adds a
mutation for a change set for each read/write transaction. This DatabaseClient can be
used in combination with SpannerTableChangeSetPoller or SpannerDatabaseChangeSetPoller to trigger data changed events for tables that do not contain a
commit timestamp column.| Modifier and Type | Class and Description |
|---|---|
static interface |
DatabaseClientWithChangeSets.AsyncRunnerWithChangeSet
AsyncRunner that automatically creates a change set. |
static interface |
DatabaseClientWithChangeSets.AsyncTransactionManagerWithChangeSet
AsyncTransactionManager that automatically creates a change set. |
static interface |
DatabaseClientWithChangeSets.ChangeSetIdGenerator
Interface for generating unique id's for change sets.
|
static interface |
DatabaseClientWithChangeSets.ChangeSetIdSupplier
Supplier of change set id's.
|
static interface |
DatabaseClientWithChangeSets.TransactionManagerWithChangeSet
TransactionManager that automatically creates a change set. |
static interface |
DatabaseClientWithChangeSets.TransactionRunnerWithChangeSet
TransactionRunner that automatically creates a change set. |
| Modifier and Type | Method and Description |
|---|---|
long |
executePartitionedUpdate(com.google.cloud.spanner.Statement stmt,
com.google.cloud.spanner.Options.UpdateOption... options) |
String |
newChangeSetId() |
static DatabaseClientWithChangeSets |
of(com.google.cloud.spanner.DatabaseClient client)
Creates a
DatabaseClient that will automatically create a change set for each
read/write transaction. |
com.google.cloud.spanner.ReadOnlyTransaction |
readOnlyTransaction() |
com.google.cloud.spanner.ReadOnlyTransaction |
readOnlyTransaction(com.google.cloud.spanner.TimestampBound bound) |
DatabaseClientWithChangeSets.TransactionRunnerWithChangeSet |
readWriteTransaction(com.google.cloud.spanner.Options.TransactionOption... options)
Creates a
TransactionRunner that automatically creates a change set. |
DatabaseClientWithChangeSets.AsyncRunnerWithChangeSet |
runAsync(com.google.cloud.spanner.Options.TransactionOption... options)
Returns an asynchronous transaction runner that automatically creates a change set for
executing a single logical transaction with retries.
|
com.google.cloud.spanner.ReadContext |
singleUse() |
com.google.cloud.spanner.ReadContext |
singleUse(com.google.cloud.spanner.TimestampBound bound) |
com.google.cloud.spanner.ReadOnlyTransaction |
singleUseReadOnlyTransaction() |
com.google.cloud.spanner.ReadOnlyTransaction |
singleUseReadOnlyTransaction(com.google.cloud.spanner.TimestampBound bound) |
DatabaseClientWithChangeSets.TransactionManagerWithChangeSet |
transactionManager(com.google.cloud.spanner.Options.TransactionOption... options)
Returns a transaction manager that automatically creates a change set.
|
DatabaseClientWithChangeSets.AsyncTransactionManagerWithChangeSet |
transactionManagerAsync(com.google.cloud.spanner.Options.TransactionOption... options)
Returns an asynchronous transaction manager that automatically creates a change set, and which
allows manual management of transaction lifecycle.
|
com.google.cloud.Timestamp |
write(Iterable<com.google.cloud.spanner.Mutation> mutations)
Writes the given mutations WITHOUT a change set id.
|
com.google.cloud.Timestamp |
write(String changeSetId,
Iterable<com.google.cloud.spanner.Mutation> mutations)
Writes the given mutations atomically to the database using the given change set id.
|
com.google.cloud.Timestamp |
writeAtLeastOnce(Iterable<com.google.cloud.spanner.Mutation> mutations)
Writes the given mutations WITHOUT a change set id.
|
com.google.cloud.Timestamp |
writeAtLeastOnce(String changeSetId,
Iterable<com.google.cloud.spanner.Mutation> mutations)
Writes the given mutations atomically to the database without replay protection using the given
change set id.
|
com.google.cloud.spanner.CommitResponse |
writeAtLeastOnceWithOptions(Iterable<com.google.cloud.spanner.Mutation> mutations,
com.google.cloud.spanner.Options.TransactionOption... options) |
com.google.cloud.spanner.CommitResponse |
writeWithOptions(Iterable<com.google.cloud.spanner.Mutation> mutations,
com.google.cloud.spanner.Options.TransactionOption... options) |
public static DatabaseClientWithChangeSets of(com.google.cloud.spanner.DatabaseClient client)
DatabaseClient that will automatically create a change set for each
read/write transaction.public String newChangeSetId()
public com.google.cloud.Timestamp write(Iterable<com.google.cloud.spanner.Mutation> mutations) throws com.google.cloud.spanner.SpannerException
write(String,
Iterable).write in interface com.google.cloud.spanner.DatabaseClientcom.google.cloud.spanner.SpannerExceptionpublic com.google.cloud.Timestamp write(String changeSetId, Iterable<com.google.cloud.spanner.Mutation> mutations) throws com.google.cloud.spanner.SpannerException
This method uses retries and replay protection internally, which means that the mutations are applied exactly once on success, or not at all if an error is returned, regardless of any failures in the underlying network. Note that if the call is cancelled or reaches deadline, it is not possible to know whether the mutations were applied without performing a subsequent database operation, but the mutations will have been applied at most once.
Example of blind write.
String changeSetId = dbClient.newChangeSetId();
long singerId = my_singer_id;
Mutation mutation = Mutation.newInsertBuilder("Singer")
.set("SingerId")
.to(singerId)
.set("FirstName")
.to("Billy")
.set("LastName")
.to("Joel")
.set("ChangeSetId")
.to(changeSetId)
.build();
dbClient.write(Collections.singletonList(mutation));
com.google.cloud.spanner.SpannerExceptionpublic com.google.cloud.Timestamp writeAtLeastOnce(Iterable<com.google.cloud.spanner.Mutation> mutations) throws com.google.cloud.spanner.SpannerException
writeAtLeastOnce(String, Iterable).writeAtLeastOnce in interface com.google.cloud.spanner.DatabaseClientcom.google.cloud.spanner.SpannerExceptionpublic com.google.cloud.Timestamp writeAtLeastOnce(String changeSetId, Iterable<com.google.cloud.spanner.Mutation> mutations) throws com.google.cloud.spanner.SpannerException
Since this method does not feature replay protection, it may attempt to apply mutations more than once; if the mutations are not idempotent, this may lead to a failure
being reported when the mutation was applied once. For example, an insert may fail with ErrorCode.ALREADY_EXISTS even though the row did not exist before this method was called. For
this reason, most users of the library will prefer to use write(Iterable) instead.
However, writeAtLeastOnce() requires only a single RPC, whereas write()
requires two RPCs (one of which may be performed in advance), and so this method may be
appropriate for latency sensitive and/or high throughput blind writing.
Example of unprotected blind write.
String changeSetId = dbClient.newChangeSetId();
long singerId = my_singer_id;
Mutation mutation = Mutation.newInsertBuilder("Singers")
.set("SingerId")
.to(singerId)
.set("FirstName")
.to("Billy")
.set("LastName")
.to("Joel")
.set("ChangeSetId")
.to(changeSetId)
.build();
dbClient.writeAtLeastOnce(changeSetId, Collections.singletonList(mutation));
com.google.cloud.spanner.SpannerExceptionpublic DatabaseClientWithChangeSets.TransactionRunnerWithChangeSet readWriteTransaction(com.google.cloud.spanner.Options.TransactionOption... options)
TransactionRunner that automatically creates a change set.
Example usage:
DatabaseClientWithChangeSets dbClientWithChangeSets = DatabaseClientWithChangeSets.of(dbClient);
TransactionRunnerWithChangeSet runner = dbClientWithChangeSets.readWriteTransaction();
long singerId = my_singer_id;
runner.run(
new TransactionCallable<Void>() {
@Override
public Void run(TransactionContext transaction) throws Exception {
String column = "FirstName";
Struct row =
transaction.readRow("Singers", Key.of(singerId), Collections.singleton(column));
String name = row.getString(column);
transaction.buffer(
Mutation.newUpdateBuilder("Singers")
.set(column).to(name.toUpperCase())
.set("ChangeSetId").to(runner.getChangeSetId())
.build());
return null;
}
});
readWriteTransaction in interface com.google.cloud.spanner.DatabaseClientpublic DatabaseClientWithChangeSets.TransactionManagerWithChangeSet transactionManager(com.google.cloud.spanner.Options.TransactionOption... options)
#readWriteTransaction() API instead.
Example usage:
DatabaseClientWithChangeSets dbClientWithChangeSets = DatabaseClientWithChangeSets.of(dbClient);
long singerId = my_singer_id;
try (TransactionManagerWithChangeSet manager = dbClientWithChangeSets.transactionManager()) {
TransactionContext txn = manager.begin();
while (true) {
String column = "FirstName";
Struct row = txn.readRow("Singers", Key.of(singerId), Collections.singleton(column));
String name = row.getString(column);
txn.buffer(
Mutation.newUpdateBuilder("Singers")
.set(column).to(name.toUpperCase())
.set("ChangeSetId").to(manager.getChangeSetId())
.build());
try {
manager.commit();
break;
} catch (AbortedException e) {
Thread.sleep(e.getRetryDelayInMillis() / 1000);
txn = manager.resetForRetry();
}
}
}
transactionManager in interface com.google.cloud.spanner.DatabaseClientpublic DatabaseClientWithChangeSets.AsyncRunnerWithChangeSet runAsync(com.google.cloud.spanner.Options.TransactionOption... options)
Example usage:
Executor executor = Executors.newSingleThreadExecutor();
DatabaseClientWithChangeSets dbClientWithChangeSets = DatabaseClientWithChangeSets.of(dbClient);
final long singerId = my_singer_id;
AsyncRunnerWithChangeSet runner = dbClientWithChangeSets.runAsync();
ApiFuture rowCount =
runner.runAsync(
new AsyncWork() { runAsync in interface com.google.cloud.spanner.DatabaseClientpublic DatabaseClientWithChangeSets.AsyncTransactionManagerWithChangeSet transactionManagerAsync(com.google.cloud.spanner.Options.TransactionOption... options)
#runAsync() API instead.
Example of using DatabaseClientWithChangeSets.AsyncTransactionManagerWithChangeSet with lambda expressions (Java
8 and higher).
DatabaseClientWithChangeSets dbClientWithChangeSets = DatabaseClientWithChangeSets.of(dbClient);
long singerId = 1L;
try (AsyncTransactionManagerWithChangeSet manager = dbClientWithChangeSets.transactionManagerAsync()) {
TransactionContextFuture txnFut = manager.beginAsync();
while (true) {
String column = "FirstName";
CommitTimestampFuture commitTimestamp =
txnFut
.then(
(txn, __) ->
txn.readRowAsync(
"Singers", Key.of(singerId), Collections.singleton(column)))
.then(
(txn, row) -> {
String name = row.getString(column);
txn.buffer(
Mutation.newUpdateBuilder("Singers")
.set(column)
.to(name.toUpperCase())
.set("ChangeSetId")
.to(manager.getChangeSetId())
.build());
return ApiFutures.immediateFuture(null);
})
.commitAsync();
try {
commitTimestamp.get();
break;
} catch (AbortedException e) {
Thread.sleep(e.getRetryDelayInMillis() / 1000);
txnFut = manager.resetForRetryAsync();
}
}
}
transactionManagerAsync in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadContext singleUse()
singleUse in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadContext singleUse(com.google.cloud.spanner.TimestampBound bound)
singleUse in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadOnlyTransaction singleUseReadOnlyTransaction()
singleUseReadOnlyTransaction in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadOnlyTransaction singleUseReadOnlyTransaction(com.google.cloud.spanner.TimestampBound bound)
singleUseReadOnlyTransaction in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadOnlyTransaction readOnlyTransaction()
readOnlyTransaction in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.ReadOnlyTransaction readOnlyTransaction(com.google.cloud.spanner.TimestampBound bound)
readOnlyTransaction in interface com.google.cloud.spanner.DatabaseClientpublic long executePartitionedUpdate(com.google.cloud.spanner.Statement stmt,
com.google.cloud.spanner.Options.UpdateOption... options)
executePartitionedUpdate in interface com.google.cloud.spanner.DatabaseClientpublic com.google.cloud.spanner.CommitResponse writeWithOptions(Iterable<com.google.cloud.spanner.Mutation> mutations, com.google.cloud.spanner.Options.TransactionOption... options) throws com.google.cloud.spanner.SpannerException
writeWithOptions in interface com.google.cloud.spanner.DatabaseClientcom.google.cloud.spanner.SpannerExceptionpublic com.google.cloud.spanner.CommitResponse writeAtLeastOnceWithOptions(Iterable<com.google.cloud.spanner.Mutation> mutations, com.google.cloud.spanner.Options.TransactionOption... options) throws com.google.cloud.spanner.SpannerException
writeAtLeastOnceWithOptions in interface com.google.cloud.spanner.DatabaseClientcom.google.cloud.spanner.SpannerExceptionCopyright © 2022 Google LLC. All rights reserved.