Search in sources :

Example 1 with TransactionRunner

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));
}
Also used : TransactionCallable(com.google.cloud.spanner.TransactionRunner.TransactionCallable) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) Timestamp(com.google.cloud.Timestamp) Struct(com.google.cloud.spanner.Struct) TransactionContext(com.google.cloud.spanner.TransactionContext) TransactionRunner(com.google.cloud.spanner.TransactionRunner) Vector(java.util.Vector)

Example 2 with TransactionRunner

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;
        }
    });
}
Also used : DatabaseClient(com.google.cloud.spanner.DatabaseClient) TransactionRunner(com.google.cloud.spanner.TransactionRunner) TransactionContext(com.google.cloud.spanner.TransactionContext) Database(com.google.cloud.spanner.Database) DatabaseAdminClient(com.google.cloud.spanner.DatabaseAdminClient) SpannerException(com.google.cloud.spanner.SpannerException) Mutation(com.google.cloud.spanner.Mutation) CreateDatabaseMetadata(com.google.spanner.admin.database.v1.CreateDatabaseMetadata) Nullable(javax.annotation.Nullable) Before(org.junit.Before)

Example 3 with TransactionRunner

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());
}
Also used : ArrayList(java.util.ArrayList) DatabaseClient(com.google.cloud.spanner.DatabaseClient) TransactionRunner(com.google.cloud.spanner.TransactionRunner) TransactionContext(com.google.cloud.spanner.TransactionContext) Database(com.google.cloud.spanner.Database) DatabaseAdminClient(com.google.cloud.spanner.DatabaseAdminClient) SpannerException(com.google.cloud.spanner.SpannerException) Mutation(com.google.cloud.spanner.Mutation) CreateDatabaseMetadata(com.google.spanner.admin.database.v1.CreateDatabaseMetadata) Nullable(javax.annotation.Nullable) Before(org.junit.Before)

Example 4 with TransactionRunner

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]
}
Also used : TransactionRunner(com.google.cloud.spanner.TransactionRunner) TransactionContext(com.google.cloud.spanner.TransactionContext) AbortedException(com.google.cloud.spanner.AbortedException) Struct(com.google.cloud.spanner.Struct)

Example 5 with TransactionRunner

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();
        }
    }
}
Also used : TransactionRunner(com.google.cloud.spanner.TransactionRunner) TransactionCallable(com.google.cloud.spanner.TransactionRunner.TransactionCallable) TransactionContext(com.google.cloud.spanner.TransactionContext) Statement(com.google.cloud.spanner.Statement) ResultSet(com.google.cloud.spanner.ResultSet) SQLException(java.sql.SQLException) CloudSpannerSQLException(nl.topicus.jdbc.exception.CloudSpannerSQLException) SpannerException(com.google.cloud.spanner.SpannerException)

Aggregations

TransactionRunner (com.google.cloud.spanner.TransactionRunner)6 TransactionContext (com.google.cloud.spanner.TransactionContext)5 SpannerException (com.google.cloud.spanner.SpannerException)3 Database (com.google.cloud.spanner.Database)2 DatabaseAdminClient (com.google.cloud.spanner.DatabaseAdminClient)2 DatabaseClient (com.google.cloud.spanner.DatabaseClient)2 Mutation (com.google.cloud.spanner.Mutation)2 Struct (com.google.cloud.spanner.Struct)2 TransactionCallable (com.google.cloud.spanner.TransactionRunner.TransactionCallable)2 CreateDatabaseMetadata (com.google.spanner.admin.database.v1.CreateDatabaseMetadata)2 ArrayList (java.util.ArrayList)2 Nullable (javax.annotation.Nullable)2 Before (org.junit.Before)2 Timestamp (com.google.cloud.Timestamp)1 AbortedException (com.google.cloud.spanner.AbortedException)1 ResultSet (com.google.cloud.spanner.ResultSet)1 Statement (com.google.cloud.spanner.Statement)1 SQLException (java.sql.SQLException)1 Vector (java.util.Vector)1 CountDownLatch (java.util.concurrent.CountDownLatch)1