use of com.google.cloud.spanner.TransactionRunner in project google-cloud-java by GoogleCloudPlatform.
the class ITTransactionTest method doBasicsTest.
private void doBasicsTest(final ReadStrategy strategy) throws InterruptedException {
final String key = uniqueKey();
// Initial value.
client.write(Arrays.asList(Mutation.newInsertBuilder("T").set("K").to(key).set("V").to(0).build()));
final int numThreads = 3;
final CountDownLatch commitBarrier = new CountDownLatch(numThreads);
final CountDownLatch complete = new CountDownLatch(numThreads);
final TransactionCallable<Long> callable = new TransactionCallable<Long>() {
@Override
public Long run(TransactionContext transaction) throws SpannerException {
Struct row = strategy.read(transaction, key);
long newValue = row.getLong(0) + 1;
transaction.buffer(Mutation.newUpdateBuilder("T").set("K").to(key).set("V").to(newValue).build());
commitBarrier.countDown();
// Synchronize so that all threads attempt to commit at the same time.
Uninterruptibles.awaitUninterruptibly(commitBarrier);
return newValue;
}
};
// We start multiple threads all attempting to update the same value concurrently. We expect
// to see at least some of the corresponding transactions abort.
final Vector<Long> results = new Vector<>();
final Vector<Timestamp> commitTimestamps = new Vector<>();
class TxnThread extends Thread {
@Override
public void run() {
TransactionRunner runner = client.readWriteTransaction();
Long result = runner.run(callable);
results.add(result);
commitTimestamps.add(runner.getCommitTimestamp());
complete.countDown();
}
}
for (int i = 0; i < numThreads; ++i) {
new TxnThread().start();
}
complete.await();
assertThat(results).hasSize(numThreads);
List<Long> expectedResults = new ArrayList<>();
for (int i = 0; i < numThreads; ++i) {
expectedResults.add(i + 1L);
}
assertThat(results).containsAllIn(expectedResults);
assertThat(Sets.newHashSet(commitTimestamps)).hasSize(numThreads);
assertThat(client.singleUse(TimestampBound.strong()).readRow("T", Key.of(key), Arrays.asList("V")).getLong(0)).isEqualTo(Long.valueOf(numThreads));
}
use of com.google.cloud.spanner.TransactionRunner in project java-docs-samples by GoogleCloudPlatform.
the class SpannerReadIT method setUp.
@Before
public void setUp() {
instanceId = System.getProperty("spanner.test.instance");
databaseId = "df-spanner-read-it";
spannerOptions = SpannerOptions.getDefaultInstance();
spanner = spannerOptions.getService();
DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
try {
adminClient.dropDatabase(instanceId, databaseId);
} catch (SpannerException e) {
// Does not exist, ignore.
}
Operation<Database, CreateDatabaseMetadata> op = adminClient.createDatabase(instanceId, databaseId, Arrays.asList("CREATE TABLE Singers " + "(singerId INT64 NOT NULL, firstName STRING(MAX) NOT NULL, " + "lastName STRING(MAX) NOT NULL,) PRIMARY KEY (singerId)", "CREATE TABLE Albums (singerId INT64 NOT NULL, albumId INT64 NOT NULL, " + "albumTitle STRING(MAX) NOT NULL,) PRIMARY KEY (singerId, albumId)"));
op.waitFor();
List<Mutation> mutations = Arrays.asList(Mutation.newInsertBuilder("singers").set("singerId").to(1L).set("firstName").to("John").set("lastName").to("Lennon").build(), Mutation.newInsertBuilder("singers").set("singerId").to(2L).set("firstName").to("Paul").set("lastName").to("Mccartney").build(), Mutation.newInsertBuilder("singers").set("singerId").to(3L).set("firstName").to("George").set("lastName").to("Harrison").build(), Mutation.newInsertBuilder("singers").set("singerId").to(4L).set("firstName").to("Ringo").set("lastName").to("Starr").build(), Mutation.newInsertBuilder("albums").set("singerId").to(1L).set("albumId").to(1L).set("albumTitle").to("Imagine").build(), Mutation.newInsertBuilder("albums").set("singerId").to(2L).set("albumId").to(1L).set("albumTitle").to("Pipes of Peace").build());
DatabaseClient dbClient = getDbClient();
TransactionRunner runner = dbClient.readWriteTransaction();
runner.run(new TransactionRunner.TransactionCallable<Void>() {
@Nullable
@Override
public Void run(TransactionContext tx) {
tx.buffer(mutations);
return null;
}
});
}
use of com.google.cloud.spanner.TransactionRunner in project java-docs-samples by GoogleCloudPlatform.
the class SpannerGroupWriteIT method setUp.
@Before
public void setUp() throws Exception {
instanceId = System.getProperty("spanner.test.instance");
databaseId = "df-spanner-groupwrite-it";
spannerOptions = SpannerOptions.getDefaultInstance();
spanner = spannerOptions.getService();
DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
try {
adminClient.dropDatabase(instanceId, databaseId);
} catch (SpannerException e) {
// Does not exist, ignore.
}
Operation<Database, CreateDatabaseMetadata> op = adminClient.createDatabase(instanceId, databaseId, Arrays.asList("CREATE TABLE users (" + "id STRING(MAX) NOT NULL, state STRING(MAX) NOT NULL) PRIMARY KEY (id)", "CREATE TABLE PendingReviews (id INT64, action STRING(MAX), " + "note STRING(MAX), userId STRING(MAX),) PRIMARY KEY (id)"));
op.waitFor();
DatabaseClient dbClient = getDbClient();
List<Mutation> mutations = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mutations.add(Mutation.newInsertBuilder("users").set("id").to(Integer.toString(i)).set("state").to("ACTIVE").build());
}
TransactionRunner runner = dbClient.readWriteTransaction();
runner.run(new TransactionRunner.TransactionCallable<Void>() {
@Nullable
@Override
public Void run(TransactionContext tx) {
tx.buffer(mutations);
return null;
}
});
String content = IntStream.range(0, 10).mapToObj(Integer::toString).collect(Collectors.joining("\n"));
tempPath = Files.createTempFile("suspicious-ids", "txt");
Files.write(tempPath, content.getBytes());
}
use of com.google.cloud.spanner.TransactionRunner in project google-cloud-java by GoogleCloudPlatform.
the class DatabaseClientSnippets method readWriteTransaction.
/**
* Example of a read write transaction.
*/
// [TARGET readWriteTransaction()]
// [VARIABLE my_singer_id]
public void readWriteTransaction(final long singerId) {
// [START readWriteTransaction]
TransactionRunner runner = dbClient.readWriteTransaction();
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()).build());
return null;
}
});
// [END readWriteTransaction]
}
use of com.google.cloud.spanner.TransactionRunner in project spanner-jdbc by olavloite.
the class TransactionThread method run.
@Override
public void run() {
TransactionRunner runner = dbClient.readWriteTransaction();
synchronized (monitor) {
try {
status = runner.run(new TransactionCallable<TransactionStatus>() {
@Override
public TransactionStatus run(TransactionContext transaction) throws Exception {
long startTime = System.currentTimeMillis();
long lastTriggerTime = startTime;
boolean transactionStartedLogged = false;
boolean stackTraceLoggedForKeepAlive = false;
boolean stackTraceLoggedForLongRunning = false;
status = TransactionStatus.RUNNING;
while (!stop) {
try {
Statement statement = statements.poll(5, TimeUnit.SECONDS);
if (statement != null) {
String sql = statement.getSql();
if (!stopStatementStrings.contains(sql)) {
resultSets.put(transaction.executeQuery(statement));
}
} else {
// keep alive
transactionStartedLogged = logTransactionStarted(transactionStartedLogged, startTime);
logger.info(String.format("%s, %s", getName(), "Transaction has been inactive for more than 5 seconds and will do a keep-alive query"));
if (!stackTraceLoggedForKeepAlive) {
logStartStackTrace();
stackTraceLoggedForKeepAlive = true;
}
try (ResultSet rs = transaction.executeQuery(Statement.of("SELECT 1"))) {
rs.next();
}
}
if (!stop && logger.logInfo() && (System.currentTimeMillis() - lastTriggerTime) > CloudSpannerDriver.getLongTransactionTrigger()) {
transactionStartedLogged = logTransactionStarted(transactionStartedLogged, startTime);
logger.info(String.format("%s, %s", getName(), "Transaction has been running for " + (System.currentTimeMillis() - startTime) + "ms"));
if (!stackTraceLoggedForLongRunning) {
logStartStackTrace();
stackTraceLoggedForLongRunning = true;
}
lastTriggerTime = System.currentTimeMillis();
}
} catch (InterruptedException e) {
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction interrupted");
stopped = true;
exception = e;
throw e;
}
}
switch(stopStatement) {
case COMMIT:
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction committed");
transaction.buffer(mutations);
break;
case ROLLBACK:
// throw an exception to force a rollback
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction rolled back");
throw new RollbackException();
case PREPARE:
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction prepare called");
XATransaction.prepareMutations(transaction, xid, mutations);
break;
case COMMIT_PREPARED:
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction commit prepared called");
XATransaction.commitPrepared(transaction, xid);
break;
case ROLLBACK_PREPARED:
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction rollback prepared called");
XATransaction.rollbackPrepared(transaction, xid);
break;
}
logDebugIfTransactionStartedLogged(transactionStartedLogged, "Transaction successfully stopped");
return TransactionStatus.SUCCESS;
}
});
commitTimestamp = runner.getCommitTimestamp();
} catch (Exception e) {
if (e.getCause() instanceof RollbackException) {
status = TransactionStatus.SUCCESS;
} else {
// if statement prevents unnecessary String.format(...) call
if (logger.logDebug()) {
logger.debug(String.format("%s, %s", getName(), "Transaction threw an exception: " + e.getMessage()));
}
status = TransactionStatus.FAIL;
exception = e;
}
} finally {
stopped = true;
monitor.notifyAll();
}
}
}
Aggregations