Resolves #719: Support `.setReadVersion()` on `ReadTransaction`

This commit is contained in:
Alec Grieser 2019-02-28 14:33:59 -08:00
parent 735c45a3b0
commit 7ef189701e
No known key found for this signature in database
GPG Key ID: CAF63551C60D3462
4 changed files with 102 additions and 27 deletions

View File

@ -40,11 +40,26 @@ class FDBTransaction extends NativeObjectWrapper implements Transaction, OptionC
public final ReadTransaction snapshot;
class ReadSnapshot implements ReadTransaction {
@Override
public boolean isSnapshot() {
return true;
}
@Override
public ReadTransaction snapshot() {
return this;
}
@Override
public CompletableFuture<Long> getReadVersion() {
return FDBTransaction.this.getReadVersion();
}
@Override
public void setReadVersion(long version) {
FDBTransaction.this.setReadVersion(version);
}
@Override
public CompletableFuture<byte[]> get(byte[] key) {
return get_internal(key, true);
@ -126,6 +141,16 @@ class FDBTransaction extends NativeObjectWrapper implements Transaction, OptionC
return getRange(range, ReadTransaction.ROW_LIMIT_UNLIMITED);
}
@Override
public void addReadConflictRangeIfNotSnapshot(byte[] keyBegin, byte[] keyEnd) {
// Do nothing
}
@Override
public void addReadConflictKeyIfNotSnapshot(byte[] key) {
// Do nothing
}
@Override
public TransactionOptions options() {
return FDBTransaction.this.options();
@ -157,6 +182,11 @@ class FDBTransaction extends NativeObjectWrapper implements Transaction, OptionC
transactionOwner = true;
}
@Override
public boolean isSnapshot() {
return false;
}
@Override
public ReadTransaction snapshot() {
return snapshot;
@ -321,11 +351,21 @@ class FDBTransaction extends NativeObjectWrapper implements Transaction, OptionC
}
}
@Override
public void addReadConflictRangeIfNotSnapshot(byte[] keyBegin, byte[] keyEnd) {
addReadConflictRange(keyBegin, keyEnd);
}
@Override
public void addReadConflictRange(byte[] keyBegin, byte[] keyEnd) {
addConflictRange(keyBegin, keyEnd, ConflictRangeType.READ);
}
@Override
public void addReadConflictKeyIfNotSnapshot(byte[] key) {
addReadConflictKey(key);
}
@Override
public void addReadConflictKey(byte[] key) {
addConflictRange(key, ByteArrayUtil.join(key, new byte[]{(byte) 0}), ConflictRangeType.READ);

View File

@ -32,7 +32,7 @@ import com.apple.foundationdb.tuple.Tuple;
* <br>
* <b>Note:</b> Client must call {@link Transaction#commit()} and wait on the result on all transactions,
* even ones that only read. This is done automatically when using the retry loops from
* {@link Database#run(Function)}. This is explained more in the intro to {@link Transaction}.
* {@link Database#run(java.util.function.Function)}. This is explained more in the intro to {@link Transaction}.
*
* @see Transaction
*/
@ -43,12 +43,71 @@ public interface ReadTransaction extends ReadTransactionContext {
*/
int ROW_LIMIT_UNLIMITED = 0;
/**
* Gets whether this transaction is a snapshot view of the database. In other words, this returns
* whether read conflict ranges are omitted for any reads done through this {@code ReadTransaction}.
* <br>
* For more information about how to use snapshot reads correctly, see
* <a href="/foundationdb/developer-guide.html#using-snapshot-reads" target="_blank">Using snapshot reads</a>.
*
* @return whether this is a snapshot view of the database with relaxed isolation properties
* @see #snapshot()
*/
boolean isSnapshot();
/**
* Return a special-purpose, read-only view of the database. Reads done through this interface are known as "snapshot reads".
* Snapshot reads selectively relax FoundationDB's isolation property, reducing
* <a href="/foundationdb/developer-guide.html#transaction-conflicts" target="_blank">Transaction conflicts</a>
* but making reasoning about concurrency harder.<br>
* <br>
* For more information about how to use snapshot reads correctly, see
* <a href="/foundationdb/developer-guide.html#using-snapshot-reads" target="_blank">Using snapshot reads</a>.
*
* @return a read-only view of this {@code ReadTransaction} with relaxed isolation properties
*/
ReadTransaction snapshot();
/**
* Gets the version at which the reads for this {@code Transaction} will access the database.
* @return the version for database reads
*/
CompletableFuture<Long> getReadVersion();
/**
* Directly sets the version of the database at which to execute reads. The
* normal operation of a transaction is to determine an appropriately recent
* version; this call overrides that behavior. If the version is set too
* far in the past, {@code past_version} errors will be thrown from read operations.
* <i>Infrequently used.</i>
*
* @param version the version at which to read from the database
*/
void setReadVersion(long version);
/**
* Adds the read conflict range that this {@code ReadTransaction} would have added as if it had read
* the given key range. If this is a {@linkplain #snapshot() snapshot} view of the database, this will
* not add the conflict range. This mirrors how reading a range through a snapshot view
* of the database does not add a conflict range for the read keys.
*
* @param keyBegin the first key in the range (inclusive)
* @param keyEnd the last key in the range (exclusive)
* @see Transaction#addReadConflictRange(byte[], byte[])
*/
void addReadConflictRangeIfNotSnapshot(byte[] keyBegin, byte[] keyEnd);
/**
* Adds the read conflict range that this {@code ReadTransaction} would have added as if it had read
* the given key. If this is a {@linkplain #snapshot() snapshot} view of the database, this will
* not add the conflict range. This mirrors how reading a key through a snapshot view
* of the database does not add a conflict range for the read key.
*
* @param key the key to add to the read conflict range set (it this is not a snapshot view of the database)
* @see Transaction#addReadConflictKey(byte[])
*/
void addReadConflictKeyIfNotSnapshot(byte[] key);
/**
* Gets a value from the database. The call will return {@code null} if the key is not
* present in the database.

View File

@ -76,31 +76,6 @@ import com.apple.foundationdb.tuple.Tuple;
*/
public interface Transaction extends AutoCloseable, ReadTransaction, TransactionContext {
/**
* Return special-purpose, read-only view of the database. Reads done through this interface are known as "snapshot reads".
* Snapshot reads selectively relax FoundationDB's isolation property, reducing
* <a href="/foundationdb/developer-guide.html#transaction-conflicts" target="_blank">Transaction conflicts</a>
* but making reasoning about concurrency harder.<br>
* <br>
* For more information about how to use snapshot reads correctly, see
* <a href="/foundationdb/developer-guide.html#using-snapshot-reads" target="_blank">Using snapshot reads</a>.
*
* @return a read-only view of this {@code Transaction} with relaxed isolation properties
*/
ReadTransaction snapshot();
/**
* Directly sets the version of the database at which to execute reads. The
* normal operation of a transaction is to determine an appropriately recent
* version; this call overrides that behavior. If the version is set too
* far in the past, {@code past_version} errors will be thrown from read operations.
* <i>Infrequently used.</i>
*
* @param version the version at which to read from the database
*/
void setReadVersion(long version);
/**
* Adds a range of keys to the transaction's read conflict ranges as if you
* had read the range. As a result, other transactions that write a key in
@ -116,7 +91,7 @@ public interface Transaction extends AutoCloseable, ReadTransaction, Transaction
* the key. As a result, other transactions that concurrently write this key
* could cause the transaction to fail with a conflict.
*
* @param key the key to be added to the range
* @param key the key to be added to the read conflict range set
*/
void addReadConflictKey(byte[] key);

View File

@ -35,6 +35,7 @@ Bindings
* Python: Removed ``fdb.init``, ``fdb.create_cluster``, and ``fdb.Cluster``. ``fdb.open`` no longer accepts a ``database_name`` parameter. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
* Java: Deprecated ``FDB.createCluster`` and ``Cluster``. The preferred way to get a ``Database`` is by using ``FDB.open``, which should work in both new and old API versions. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
* Java: Removed ``Cluster(long cPtr, Executor executor)`` constructor. This is API breaking for any code that has subclassed the ``Cluster`` class and is not protected by API versioning. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
* Java: Several methods relevant to read-only transactions have been moved into the ``ReadTransaction`` interface.
* Ruby: Removed ``FDB.init``, ``FDB.create_cluster``, and ``FDB.Cluster``. ``FDB.open`` no longer accepts a ``database_name`` parameter. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
* Golang: Deprecated ``fdb.StartNetwork``, ``fdb.Open``, ``fdb.MustOpen``, and ``fdb.CreateCluster`` and added ``fdb.OpenDatabase`` and ``fdb.MustOpenDatabase``. The preferred way to start the network and get a ``Database`` is by using ``FDB.OpenDatabase`` or ``FDB.OpenDefault``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
* Flow: Deprecated ``API::createCluster`` and ``Cluster`` and added ``API::createDatabase``. The preferred way to get a ``Database`` is by using ``API::createDatabase``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_