Refine search
@Override public Void run(TransactionContext transaction) throws SpannerException { client.readOnlyTransaction().getReadTimestamp(); return null; } });
/** Example of read only transaction. */ // [TARGET readOnlyTransaction()] // [VARIABLE my_singer_id] // [VARIABLE my_album_id] public String readOnlyTransaction(long singerId, long albumId) { // [START readOnlyTransaction] String singerColumn = "FirstName"; String albumColumn = "AlbumTitle"; String albumTitle = null; // ReadOnlyTransaction should be closed to prevent resource leak. try (ReadOnlyTransaction txn = dbClient.readOnlyTransaction()) { 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 readOnlyTransaction] return albumTitle; }
/** Example of single use read only transaction. */ // [TARGET singleUseReadOnlyTransaction()] // [VARIABLE my_singer_id] public Timestamp singleUseReadOnlyTransaction(long singerId) { // [START singleUseReadOnlyTransaction] String column = "FirstName"; ReadOnlyTransaction txn = dbClient.singleUseReadOnlyTransaction(); Struct row = txn.readRow("Singers", Key.of(singerId), Collections.singleton(column)); row.getString(column); Timestamp timestamp = txn.getReadTimestamp(); // [END singleUseReadOnlyTransaction] return timestamp; }
@Test public void query() { // We don't exhaustively test query with all modes - the read tests give us enough confidence // that transaction options are generated appropriately. Just do one test for each type of // context to ensure that transaction options are set at all. History expected = history.get(2); TimestampBound bound = TimestampBound.ofReadTimestamp(expected.timestamp); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = queryRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); readContext = client.readOnlyTransaction(bound); row = queryRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); readContext.close(); row = queryRow(client.singleUse(bound)); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); }
@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); }
static void readOnlyTransaction(DatabaseClient dbClient) { // ReadOnlyTransaction must be closed by calling close() on it to release resources held by it. // We use a try-with-resource block to automatically do so. try (ReadOnlyTransaction transaction = dbClient.readOnlyTransaction()) { ResultSet queryResultSet = transaction.executeQuery( Statement.of("SELECT SingerId, AlbumId, AlbumTitle FROM Albums")); while (queryResultSet.next()) { System.out.printf( "%d %d %s\n", queryResultSet.getLong(0), queryResultSet.getLong(1), queryResultSet.getString(2)); } ResultSet readResultSet = transaction.read( "Albums", KeySet.all(), Arrays.asList("SingerId", "AlbumId", "AlbumTitle")); while (readResultSet.next()) { System.out.printf( "%d %d %s\n", readResultSet.getLong(0), readResultSet.getLong(1), readResultSet.getString(2)); } } } // [END spanner_read_only_transaction]
private ResultSet readPrimaryKeyInfo(ReadOnlyTransaction tx) { return tx.executeQuery( Statement.of( "SELECT t.table_name, t.column_name, t.column_ordering" + " FROM information_schema.index_columns AS t " + " WHERE t.index_name = 'PRIMARY_KEY' AND t.table_catalog = ''" + " AND t.table_schema = ''" + " ORDER BY t.table_name, t.ordinal_position")); } }
@Test public void singleUseReadOnlyTransactionDoesntReturnTransactionMetadata() { PartialResultSet resultSet = PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); mockRead(resultSet); ReadOnlyTransaction txn = session.singleUseReadOnlyTransaction(TimestampBound.strong()); assertThat(txn.readRow("Dummy", Key.of(), Arrays.asList("C"))).isNull(); // For now, getReadTimestamp() will raise an ISE because it hasn't seen a timestamp. It would // be better for the read to fail with an INTERNAL error, but we can't do that until txn // metadata is returned for failed reads (e.g., table-not-found) as well as successful ones. // TODO(user): Fix this. expectedException.expect(IllegalStateException.class); txn.getReadTimestamp(); }
@Override public Timestamp getReadTimestamp() { return txn.getReadTimestamp(); } }
@Test public void multiUseReadOnlyTransactionReturnsEmptyTransactionMetadata() { Transaction txnMetadata = Transaction.newBuilder().setId(ByteString.copyFromUtf8("x")).build(); PartialResultSet resultSet = PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); Mockito.when(rpc.beginTransaction(Mockito.<BeginTransactionRequest>any(), Mockito.eq(options))) .thenReturn(txnMetadata); mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.INTERNAL)); txn.readRow("Dummy", Key.of(), Arrays.asList("C")); }
@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()); }
/** Example of single use read only transaction with timestamp bound. */ // [TARGET singleUseReadOnlyTransaction(TimestampBound)] // [VARIABLE my_singer_id] public Timestamp singleUseReadOnlyTransactionTimestamp(long singerId) { // [START singleUseReadOnlyTransactionTimestamp] String column = "FirstName"; ReadOnlyTransaction txn = dbClient.singleUseReadOnlyTransaction(TimestampBound.ofMaxStaleness(10, TimeUnit.SECONDS)); Struct row = txn.readRow("Singers", Key.of(singerId), Collections.singleton(column)); row.getString(column); Timestamp timestamp = txn.getReadTimestamp(); // [END singleUseReadOnlyTransactionTimestamp] return timestamp; }
private ResultSet readTableInfo(ReadOnlyTransaction tx) { // retrieve schema information for all tables, as well as aggregating the // number of indexes that cover each column. this will be used to estimate // the number of cells (table column plus indexes) mutated in an upsert operation // in order to stay below the 20k threshold return tx.executeQuery( Statement.of( "SELECT" + " c.table_name" + " , c.column_name" + " , c.spanner_type" + " , (1 + COALESCE(t.indices, 0)) AS cells_mutated" + " FROM (" + " SELECT c.table_name, c.column_name, c.spanner_type, c.ordinal_position" + " FROM information_schema.columns as c" + " WHERE c.table_catalog = '' AND c.table_schema = '') AS c" + " LEFT OUTER JOIN (" + " SELECT t.table_name, t.column_name, COUNT(*) AS indices" + " FROM information_schema.index_columns AS t " + " WHERE t.index_name != 'PRIMARY_KEY' AND t.table_catalog = ''" + " AND t.table_schema = ''" + " GROUP BY t.table_name, t.column_name) AS t" + " USING (table_name, column_name)" + " ORDER BY c.table_name, c.ordinal_position")); }
private void insertAndReadAgain( ReadOnlyTransaction readContext, Timestamp expectedTimestamp, @Nullable String expectedValue) { writeNewValue(client, history.size(), null); Struct row = readRow(readContext); if (expectedValue == null) { assertThat(row).isNull(); } else { assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expectedValue); } assertThat(readContext.getReadTimestamp()).isEqualTo(expectedTimestamp); }
@Test public void multiUseReadOnlyTransactionReturnsMissingTimestamp() { Transaction txnMetadata = Transaction.newBuilder().setId(ByteString.copyFromUtf8("x")).build(); PartialResultSet resultSet = PartialResultSet.newBuilder() .setMetadata(newMetadata(Type.struct(Type.StructField.of("C", Type.string())))) .build(); Mockito.when(rpc.beginTransaction(Mockito.<BeginTransactionRequest>any(), Mockito.eq(options))) .thenReturn(txnMetadata); mockRead(resultSet); ReadOnlyTransaction txn = session.readOnlyTransaction(TimestampBound.strong()); expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.INTERNAL)); txn.readRow("Dummy", Key.of(), Arrays.asList("C")); }
@Test public void singleMinReadTimestamp() { int minimumIndex = 2; History minimum = history.get(minimumIndex); NavigableMap<Timestamp, String> possibleValues = new TreeMap<>(); for (History item : history.subList(minimumIndex, history.size())) { possibleValues.put(item.timestamp, item.value); } TimestampBound bound = TimestampBound.ofMinReadTimestamp(minimum.timestamp); 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 multiStrong() { setUpPrivateDatabase(); History expected = history.get(history.size() - 1); try (ReadOnlyTransaction readContext = client.readOnlyTransaction()) { Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isAtLeast(expected.timestamp); insertAndReadAgain(readContext, readContext.getReadTimestamp(), expected.value); } }
/** 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; }
private void preparePkMetadata(ReadOnlyTransaction tx, List<Struct> rows) { Type type = Type.struct( Type.StructField.of("table_name", Type.string()), Type.StructField.of("column_name", Type.string()), Type.StructField.of("column_ordering", Type.string())); when(tx.executeQuery( argThat( new ArgumentMatcher<Statement>() { @Override public boolean matches(Object argument) { if (!(argument instanceof Statement)) { return false; } Statement st = (Statement) argument; return st.getSql().contains("information_schema.index_columns"); } }))) .thenReturn(ResultSets.forRows(type, rows)); }
@Override public Timestamp getReadTimestamp() { return txn.getReadTimestamp(); } }