FDBRecordContext extends FDBTransactionContext implements AutoCloseable { public <T> T get(CompletableFuture<T> future) throws InterruptedException, ExecutionException { return database.get(future); } protected  FDBRecordContext(@Nonnull FDBDatabase fdb,
                               @Nonnull Transaction transaction,
                               @Nonnull FDBRecordContextConfig config); @Nullable String getTransactionId(); long getTimeoutMillis(); final void logTransaction(); boolean isLogged(); @API(API.Status.INTERNAL) @VisibleForTesting long getTrackOpenTimeNanos(); boolean isClosed(); @Override void close(); void commit(); CompletableFuture<Void> commitAsync(); @Override @Nonnull Transaction ensureActive(); synchronized long setReadVersion(long readVersion); @Nonnull synchronized CompletableFuture<Long> getReadVersionAsync(); @SpotBugsSuppressWarnings(value = "UG_SYNC_SET_UNSYNC_GET", justification = "read only one field and avoid blocking in setReadVersion") long getReadVersion(); boolean hasReadVersion(); @Nonnull ReadTransaction readTransaction(boolean snapshot); long getTransactionAge(); long getTransactionCreateTime(); @API(API.Status.INTERNAL) void setDirtyStoreState(boolean dirtyStoreState); @API(API.Status.INTERNAL) boolean hasDirtyStoreState(); synchronized void addCommitCheck(@Nonnull CommitCheckAsync check); synchronized void addCommitCheck(@Nonnull CompletableFuture<Void> check); @Nonnull CompletableFuture<Void> runCommitChecks(); @Nonnull PostCommit getOrCreatePostCommit(@Nonnull String name, @Nonnull Function<String, PostCommit> ifNotExists); @Nullable PostCommit getPostCommit(@Nonnull String name); void addPostCommit(@Nonnull String name, @Nonnull PostCommit postCommit); void addPostCommit(@Nonnull PostCommit postCommit); @Nullable PostCommit removePostCommit(@Nonnull String name); void addAfterCommit(@Nonnull AfterCommit afterCommit); @Deprecated @API(API.Status.DEPRECATED) void runAfterCommits(); long getCommittedVersion(); @Nullable @SpotBugsSuppressWarnings(value = {"EI"}, justification = "avoids copy") byte[] getVersionStamp(); @Nonnull CompletableFuture<byte[]> getMetaDataVersionStampAsync(@Nonnull IsolationLevel isolationLevel); @Nullable byte[] getMetaDataVersionStamp(@Nonnull IsolationLevel isolationLevel); void setMetaDataVersionStamp(); @Nullable T asyncToSync(FDBStoreTimer.Wait event, @Nonnull CompletableFuture<T> async); T join(CompletableFuture<T> future); T joinNow(CompletableFuture<T> future); T get(CompletableFuture<T> future); void timeReadSampleKey(byte[] key); @Nullable Map<String, String> getMdcContext(); @Nonnull FDBDatabaseRunner newRunner(); int claimLocalVersion(); @Deprecated @Nullable byte[] addVersionMutation(@Nonnull byte[] key, @Nonnull byte[] value); @Nullable byte[] addVersionMutation(@Nonnull MutationType mutationType, @Nonnull byte[] key, @Nonnull byte[] value); @Nullable byte[] removeVersionMutation(@Nonnull byte[] key); @Nullable byte[] updateVersionMutation(@Nonnull MutationType mutationType, @Nonnull byte[] key, @Nonnull byte[] value,
                                        @Nonnull BiFunction<byte[], byte[], byte[]> remappingFunction); @Nullable FDBDatabase.WeakReadSemantics getWeakReadSemantics(); @Nonnull FDBTransactionPriority getPriority(); void setHookForAsyncToSync(@Nonnull Consumer<FDBStoreTimer.Wait> hook); boolean hasHookForAsyncToSync(); static final int MAX_TR_ID_SIZE; }
@Test public void manyParallelReadVersions() throws InterruptedException, ExecutionException { final FDBStoreTimer timer = new FDBStoreTimer(); try (FDBRecordContext context = fdb.openContext(null, timer)) { List<CompletableFuture<Long>> futures = Stream.generate(context::getReadVersionAsync) .limit(10) .collect(Collectors.toList()); List<Long> readVersions = AsyncUtil.getAll(futures).get(); long firstReadVersion = readVersions.get(0); for (long readVersion : readVersions) { assertEquals(firstReadVersion, readVersion); } assertEquals(1, timer.getCount(FDBStoreTimer.Events.GET_READ_VERSION)); } }