private TimestampBound getRandomBound() { Date date = new Date(); switch (RANDOM.nextInt(3)) { case 0: return TimestampBound.strong(); case 1: return TimestampBound.ofExactStaleness(STALENESS_MILLISEC, TimeUnit.MILLISECONDS); default: return TimestampBound.ofReadTimestamp( Timestamp.of(new Date(date.getTime() - STALENESS_MILLISEC))); } }
@Test public void exactStalenessNegative() { expectedException.expect(IllegalArgumentException.class); TimestampBound.ofExactStaleness(-1, TimeUnit.SECONDS); }
/** 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; }
@Test public void stalenessSourceUnits() { long num = 7; for (TimeUnit units : TimeUnit.values()) { TimestampBound bound = TimestampBound.ofExactStaleness(num, units); assertThat(bound.getExactStaleness(TimeUnit.NANOSECONDS)) .named(units.toString()) .isEqualTo(units.toNanos(num)); } }
@Test public void multiExactStaleness() { setUpPrivateDatabase(); // See singleExactStaleness() for why we pick this timestamp. We expect to see no value. long deadlineNanoTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(1); long stalenessNanos = 1 + deadlineNanoTime - history.get(0).minCommitNanoTime; try (ReadOnlyTransaction readContext = client.readOnlyTransaction( TimestampBound.ofExactStaleness(stalenessNanos, TimeUnit.NANOSECONDS))) { Struct row = readRow(readContext); assertThat(row).isNull(); assertThat(readContext.getReadTimestamp().toSqlTimestamp()) .isLessThan(history.get(0).timestamp.toSqlTimestamp()); insertAndReadAgain(readContext, readContext.getReadTimestamp(), null); } }
@Test public void exactStaleness() { TimestampBound bound = TimestampBound.ofExactStaleness(3140, TimeUnit.MILLISECONDS); assertThat(bound.getMode()).isEqualTo(Mode.EXACT_STALENESS); assertThat(bound.getExactStaleness(TimeUnit.SECONDS)).isEqualTo(3); assertThat(bound.getExactStaleness(TimeUnit.MILLISECONDS)).isEqualTo(3140); assertThat(bound.getExactStaleness(TimeUnit.MICROSECONDS)).isEqualTo(3140000); assertThat(bound.getExactStaleness(TimeUnit.NANOSECONDS)).isEqualTo(3140000000L); assertThat(bound.toString()).isEqualTo("exact_staleness: 3.140s"); assertProto(bound, "exact_staleness { seconds: 3 nanos: 140000000 }"); }
@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 equalsAndHashCode() { Timestamp ts = Timestamp.ofTimeSecondsAndNanos(1444662894L, 0); Timestamp ts2 = Timestamp.ofTimeSecondsAndNanos(1444662895L, 0); int staleness = 5; EqualsTester tester = new EqualsTester(); tester.addEqualityGroup(TimestampBound.strong(), TimestampBound.strong()); tester.addEqualityGroup(TimestampBound.ofReadTimestamp(ts), TimestampBound.ofReadTimestamp(ts)); tester.addEqualityGroup(TimestampBound.ofReadTimestamp(ts2)); tester.addEqualityGroup( TimestampBound.ofMinReadTimestamp(ts), TimestampBound.ofMinReadTimestamp(ts)); tester.addEqualityGroup(TimestampBound.ofMinReadTimestamp(ts2)); tester.addEqualityGroup( TimestampBound.ofExactStaleness(staleness, TimeUnit.SECONDS), TimestampBound.ofExactStaleness(staleness, TimeUnit.SECONDS)); tester.addEqualityGroup(TimestampBound.ofExactStaleness(staleness, TimeUnit.MILLISECONDS)); tester.addEqualityGroup( TimestampBound.ofMaxStaleness(staleness, TimeUnit.SECONDS), TimestampBound.ofMaxStaleness(staleness, TimeUnit.SECONDS)); tester.addEqualityGroup(TimestampBound.ofMaxStaleness(staleness, TimeUnit.MILLISECONDS)); tester.testEquals(); }
@Test public void serialization() throws Exception { reserializeAndAssert(TimestampBound.strong()); reserializeAndAssert(TimestampBound.ofExactStaleness(10, TimeUnit.NANOSECONDS)); reserializeAndAssert(TimestampBound.ofMaxStaleness(100, TimeUnit.DAYS)); reserializeAndAssert(TimestampBound.ofMinReadTimestamp(Timestamp.now())); reserializeAndAssert(TimestampBound.ofReadTimestamp(Timestamp.now())); }
static void readStaleData(DatabaseClient dbClient) { ResultSet resultSet = dbClient .singleUse(TimestampBound.ofExactStaleness(15, TimeUnit.SECONDS)) .read("Albums", KeySet.all(), Arrays.asList("SingerId", "AlbumId", "MarketingBudget")); while (resultSet.next()) { System.out.printf( "%d %d %s\n", resultSet.getLong(0), resultSet.getLong(1), resultSet.isNull(2) ? "NULL" : resultSet.getLong("MarketingBudget")); } } // [END spanner_read_stale_data]