Refine search
/** Example of read only transaction with timestamp bound. */ // [TARGET readOnlyTransaction(TimestampBound)] // [VARIABLE my_singer_id] // [VARIABLE my_album_id] public String readOnlyTransactionTimestamp(long singerId, long albumId) { // [START readOnlyTransactionTimestamp] String singerColumn = "FirstName"; String albumColumn = "AlbumTitle"; String albumTitle = null; // ReadOnlyTransaction should be closed to prevent resource leak. try (ReadOnlyTransaction txn = dbClient.readOnlyTransaction(TimestampBound.ofExactStaleness(10, TimeUnit.SECONDS))) { Struct singerRow = txn.readRow("Singers", Key.of(singerId), Collections.singleton(singerColumn)); Struct albumRow = txn.readRow("Albums", Key.of(singerId, albumId), Collections.singleton(albumColumn)); singerRow.getString(singerColumn); albumTitle = albumRow.getString(albumColumn); } // [END readOnlyTransactionTimestamp] return albumTitle; }
@Override public Status delete(String table, String key) { try { dbClient.writeAtLeastOnce(Arrays.asList(Mutation.delete(table, Key.of(key)))); } catch (Exception e) { LOGGER.log(Level.INFO, "delete()", e); return Status.ERROR; } return Status.OK; }
@Test public void partitionedDML() { executeUpdate(DML_COUNT, INSERT_DML); assertThat( client .singleUse(TimestampBound.strong()) .readRow("T", Key.of("boo1"), Arrays.asList("V")) .getLong(0)) .isEqualTo(1); long rowCount = client.executePartitionedUpdate(Statement.of(UPDATE_DML)); // Note: With PDML there is a possibility of network replay or partial update to occur, causing // this assert to fail. We should remove this assert if it is a recurring failure in IT tests. assertThat(rowCount).isEqualTo(DML_COUNT); assertThat( client .singleUse(TimestampBound.strong()) .readRow("T", Key.of("boo1"), Arrays.asList("V")) .getLong(0)) .isEqualTo(100); rowCount = client.executePartitionedUpdate(Statement.of(DELETE_DML)); assertThat(rowCount).isEqualTo(DML_COUNT); assertThat( client .singleUse(TimestampBound.strong()) .readRow("T", Key.of("boo1"), Arrays.asList("V"))) .isNull(); }
private void executeQuery(long expectedCount, final String... stmts) { final TransactionCallable<Long> callable = new TransactionCallable<Long>() { @Override public Long run(TransactionContext transaction) { long rowCount = 0; for (final String stmt : stmts) { ResultSet resultSet = transaction.executeQuery(Statement.of(stmt)); assertThat(resultSet.next()).isFalse(); assertThat(resultSet.getStats()).isNotNull(); rowCount += resultSet.getStats().getRowCountExact(); } return rowCount; } }; TransactionRunner runner = client.readWriteTransaction(); Long rowCount = runner.run(callable); assertThat(rowCount).isEqualTo(expectedCount); }
@Test public void rollback() { TransactionManager manager = client.transactionManager(); TransactionContext txn = manager.begin(); txn.buffer( Mutation.newInsertBuilder("T").set("K").to("Key2").set("BoolValue").to(true).build()); manager.rollback(); assertThat(manager.getState()).isEqualTo(TransactionState.ROLLED_BACK); // Row should not have been inserted. assertThat(client.singleUse().readRow("T", Key.of("Key2"), Arrays.asList("K", "BoolValue"))) .isNull(); }
@Test public void analyzePlan() { Statement statement = Statement.of("SELECT 1 AS column UNION ALL SELECT 2"); ResultSet resultSet = statement.analyzeQuery(client.singleUse(TimestampBound.strong()), QueryAnalyzeMode.PLAN); assertThat(resultSet.next()).isFalse(); assertThat(resultSet.getType()).isEqualTo(Type.struct(StructField.of("column", Type.int64()))); ResultSetStats receivedStats = resultSet.getStats(); assertThat(receivedStats).isNotNull(); assertThat(receivedStats.hasQueryPlan()).isTrue(); assertThat(receivedStats.hasQueryStats()).isFalse(); }
TransactionRunner runner = client.readWriteTransaction(); runner.run(callable); keys.addKey(Key.of(key1)).addKey(Key.of(key2)); ResultSet resultSet = client.singleUse(TimestampBound.strong()).read("T", keys.build(), Arrays.asList("K")); int rowCount = 0; while (resultSet.next()) { rowCount++; assertThat(rowCount).isEqualTo(2);
private List<Struct> resultRows(Statement statement, Type expectedRowType) { ArrayList<Struct> results = new ArrayList<>(); ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); while (resultSet.next()) { Struct row = resultSet.getCurrentRowAsStruct(); results.add(row); } assertThat(resultSet.getType()).isEqualTo(expectedRowType); assertThat(resultSet.next()).isFalse(); return results; }
@Test public void indexPointReadNotFound() { Struct row = client .singleUse(TimestampBound.strong()) .readRowUsingIndex(TABLE_NAME, INDEX_NAME, Key.of("v999"), ALL_COLUMNS); assertThat(row).isNull(); }
@Test public void singleReadTimestamp() { History expected = history.get(2); TimestampBound bound = TimestampBound.ofReadTimestamp(expected.timestamp); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); row = readRow(client.singleUse(bound)); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); }
@Test public void emptyRead() { ResultSet resultSet = client .singleUse(TimestampBound.strong()) .read( TABLE_NAME, KeySet.range(KeyRange.closedOpen(Key.of("k99"), Key.of("z"))), ALL_COLUMNS); assertThat(resultSet.next()).isFalse(); assertThat(resultSet.getType()).isEqualTo(TABLE_TYPE); }
@Test public void indexEmptyRead() { ResultSet resultSet = client .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, INDEX_NAME, KeySet.range(KeyRange.closedOpen(Key.of("v99"), Key.of("z"))), ALL_COLUMNS); assertThat(resultSet.next()).isFalse(); assertThat(resultSet.getType()).isEqualTo(TABLE_TYPE); }
limit != 0 ? client .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, INDEX_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) : client .singleUse(TimestampBound.strong()) .readUsingIndex(TABLE_NAME, INDEX_NAME, keySet, ALL_COLUMNS); break; case DESC_INDEX: limit != 0 ? client .singleUse(TimestampBound.strong()) .readUsingIndex( TABLE_NAME, DESC_INDEX_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) : client .singleUse(TimestampBound.strong()) .readUsingIndex(TABLE_NAME, DESC_INDEX_NAME, keySet, ALL_COLUMNS); break; limit != 0 ? client .singleUse(TimestampBound.strong()) .read(TABLE_NAME, keySet, ALL_COLUMNS, Options.limit(limit)) : client.singleUse(TimestampBound.strong()).read(TABLE_NAME, keySet, ALL_COLUMNS); break; default:
@Test public void rowsAreSnapshots() { List<Struct> rows = new ArrayList<>(); ResultSet resultSet = client .singleUse(TimestampBound.strong()) .read( TABLE_NAME, KeySet.newBuilder() .addKey(Key.of("k2")) .addKey(Key.of("k3")) .addKey(Key.of("k4")) .build(), ALL_COLUMNS); while (resultSet.next()) { rows.add(resultSet.getCurrentRowAsStruct()); } assertThat(rows.size()).isEqualTo(3); assertThat(rows.get(0).getString(0)).isEqualTo("k2"); assertThat(rows.get(0).getString(1)).isEqualTo("v2"); assertThat(rows.get(1).getString(0)).isEqualTo("k3"); assertThat(rows.get(1).getString(1)).isEqualTo("v3"); assertThat(rows.get(2).getString(0)).isEqualTo("k4"); assertThat(rows.get(2).getString(1)).isEqualTo("v4"); }
keys.addKey(Key.of(key)); .singleUse(TimestampBound.strong()) .read("T", keys.build(), Arrays.asList("K", "BytesValue")); while (resultSet.next()) { String key = resultSet.getString(0); ByteArray value = resultSet.getBytes(1); assertThat(expected).containsKey(key); ByteArray expectedValue = expected.remove(key); assertThat(value).isEqualTo(expectedValue); assertThat(expected).isEmpty(); pass = true; } finally {
"CREATE TABLE T ( K STRING(MAX) NOT NULL, V STRING(MAX) ) PRIMARY KEY (K)"); DatabaseClient client = env.getTestHelper().getDatabaseClient(populatedDb); client.writeAtLeastOnce( asList( Mutation.newInsertBuilder("T").set("K").to("k1").set("V").to("v1").build(), Statement.newBuilder("SELECT K, V FROM T WHERE K >= @min AND K < @max ORDER BY K ASC") .bind("min") .to("k13") .to("k32") .build(); ResultSet resultSet = statement.executeQuery(client.singleUse(TimestampBound.strong())); assertThat(resultSet.next()).isTrue(); assertThat(resultSet.getType()) .isEqualTo( Type.struct(StructField.of("K", Type.string()), StructField.of("V", Type.string()))); assertThat(resultSet.getString(0)).isEqualTo("k2"); assertThat(resultSet.getString(1)).isEqualTo("v2"); assertThat(resultSet.next()).isTrue();
@Test public void singleExactStaleness() { // TODO(user): Use a shorter deadline (when supported) and pass on the call to Cloud Spanner. long deadlineNanoTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(1); // The only exact staleness values that can be tested reliably are before the first item or // later than the last item: we choose the former. // // Pick a staleness that is "guaranteed" not to observe the first write. Note that this // guarantee doesn't strictly hold in the absence of enforced read deadlines, but we use a // deadline large enough to make it practically true. long stalenessNanos = 1 + deadlineNanoTime - history.get(0).minCommitNanoTime; TimestampBound bound = TimestampBound.ofExactStaleness(stalenessNanos, TimeUnit.NANOSECONDS); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = readRow(readContext); assertThat(row).isNull(); assertThat(readContext.getReadTimestamp().toSqlTimestamp()) .isLessThan(history.get(0).timestamp.toSqlTimestamp()); row = readRow(client.singleUse(bound)); assertThat(row).isNull(); }
@Test public void singleMaxStaleness() { History minimum = history.get(2); NavigableMap<Timestamp, String> possibleValues = new TreeMap<>(); for (History item : history.subList(2, history.size())) { possibleValues.put(item.timestamp, item.value); } // Pick a staleness that cannot precede the second write (which, in practice, is the staleness // that exceeds the minimum commit time for the subsequent write). long stalenessNanos = System.nanoTime() - history.get(3).minCommitNanoTime; TimestampBound bound = TimestampBound.ofMaxStaleness(stalenessNanos, TimeUnit.NANOSECONDS); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(readContext.getReadTimestamp()).isAtLeast(minimum.timestamp); assertThat(row.getString(0)) .isEqualTo(possibleValues.floorEntry(readContext.getReadTimestamp()).getValue()); row = readRow(client.singleUse(bound)); assertThat(row).isNotNull(); assertThat(row.getString(0)).isIn(possibleValues.values()); }
@Test public void singleStrong() { History expected = history.get(history.size() - 1); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(); Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isAtLeast(expected.timestamp); row = readRow(client.singleUse()); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); }