com.apple.foundationdb

## Interface Transaction

All Superinterfaces:
  java.lang.AutoCloseable, ReadTransaction, ReadTransactionContext, TransactionContext

    public interface Transaction
    extends java.lang.AutoCloseable, ReadTransaction, TransactionContext

A Transaction represents a FoundationDB database transaction. All operations on FoundationDB take place, explicitly or implicitly, through a Transaction.
In FoundationDB, a transaction is a mutable snapshot of a database. All read and write operations on a transaction see and modify an otherwise-unchanging version of the database and only change the underlying database if and when the transaction is committed. Read operations do see the effects of previous write operations on the same transaction. Committing a transaction usually succeeds in the absence of conflicts.
Transactions group operations into a unit with the properties of atomicity, isolation, and durability. Transactions also provide the ability to maintain an application's invariants or integrity constraints, supporting the property of consistency. Together these properties are known as ACID.
Transactions are also causally consistent: once a transaction has been successfully committed, all subsequently created transactions will see the modifications made by it. The most convenient way for a developer to manage the lifecycle and retrying of a `Transaction` is to use `Database.run(Function)`. Otherwise, the client must have retry logic for fatal failures, failures to commit, and other transient errors.
Keys and values in FoundationDB are byte arrays. To encode other data types, see the `Tuple API` and tuple layer documentation.
When used as a `TransactionContext`, the methods `run()` and `runAsync()` on a `Transaction` will simply attempt the operations without any retry loop.
Note: Client must call `commit()` and wait on the result on all transactions, even ones that only read. This is done automatically when using the retry loops from `Database.run(Function)`. This is because outstanding reads originating from a `Transaction` will be cancelled when a `Transaction` is garbage collected. Since the garbage collector reserves the right to collect an in-scope object if it determines that there are no subsequent references it it, this can happen in seemingly innocuous situations. `CompletableFuture`s returned from `commit()` will block until all reads are complete, thereby saving the calling code from this potentially confusing situation.
Note: All keys with a first byte of `0xff` are reserved for internal use.
Note: Java transactions automatically set the `TransactionOptions.setUsedDuringCommitProtectionDisable()` option. This is because the Java bindings disallow use of `Transaction` objects after `onError(java.lang.Throwable)` is called.
Note: `Transaction` objects must be `closed` when no longer in use in order to free any associated resources.

### Field Summary

### Fields inherited from interface com.apple.foundationdb.ReadTransaction

`ROW_LIMIT_UNLIMITED`

### Method Summary

All Methods Instance Methods Abstract Methods Deprecated Methods
`void` `addReadConflictKey(byte[] key)` Adds a key to the transaction's read conflict ranges as if you had read the key.
`void` `addReadConflictRange(byte[] keyBegin, byte[] keyEnd)` Adds a range of keys to the transaction's read conflict ranges as if you had read the range.
`void` `addWriteConflictKey(byte[] key)` Adds a key to the transaction's write conflict ranges as if you had written the key.
`void` `addWriteConflictRange(byte[] keyBegin, byte[] keyEnd)` Adds a range of keys to the transaction's write conflict ranges as if you had cleared the range.
`void` `cancel()` Cancels the `Transaction`.
`void` `clear(byte[] key)` Clears a given key from the database.
`void` `clear(byte[] beginKey, byte[] endKey)` Clears a range of keys in the database.
`void` `clear(Range range)` Clears a range of keys in the database.
`void` `clearRangeStartsWith(byte[] prefix)` Deprecated.
`void` `close()` Close the `Transaction` object and release any associated resources.
`java.util.concurrent.CompletableFuture<java.lang.Void>` `commit()` Commit this `Transaction`.
`java.lang.Long` `getCommittedVersion()` Gets the version number at which a successful commit modified the database.
`Database` `getDatabase()` Returns the `Database` that this `Transaction` is interacting with.
`java.util.concurrent.CompletableFuture<byte[]>` `getVersionstamp()` Returns a future which will contain the versionstamp which was used by any versionstamp operations in this transaction.
`void` `mutate(MutationType optype, byte[] key, byte[] param)` An atomic operation is a single database command that carries out several logical steps: reading the value of a key, performing a transformation on that value, and writing the result.
`java.util.concurrent.CompletableFuture<Transaction>` `onError(java.lang.Throwable e)` Resets a transaction and returns a delayed signal for error recovery.
`<T> T` `run(java.util.function.Function<? super Transaction,T> retryable)` Run a function once against this `Transaction`.
`<T> java.util.concurrent.CompletableFuture<T>` `runAsync(java.util.function.Function<? super Transaction,? extends java.util.concurrent.CompletableFuture<T>> retryable)` Run a function once against this `Transaction`.
`void` `set(byte[] key, byte[] value)` Sets the value for a given key.
`void` `setReadVersion(long version)` Directly sets the version of the database at which to execute reads.
`ReadTransaction` `snapshot()` Return special-purpose, read-only view of the database.
`java.util.concurrent.CompletableFuture<java.lang.Void>` `watch(byte[] key)` Creates a watch that will become ready when it reports a change to the value of the specified key. A watch's behavior is relative to the transaction that created it.

### Methods inherited from interface com.apple.foundationdb.ReadTransaction

`get, getKey, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getRange, getReadVersion, options`

### Methods inherited from interface com.apple.foundationdb.ReadTransactionContext

`getExecutor, read, readAsync`

### Method Detail

#### snapshot

    ReadTransaction snapshot()

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 Transaction conflicts but making reasoning about concurrency harder.
For more information about how to use snapshot reads correctly, see Using snapshot reads.

Returns:
  a read-only view of this `Transaction` with relaxed isolation properties

#### setReadVersion

    void setReadVersion(long version)

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, `past_version` errors will be thrown from read operations. Infrequently used.

Parameters:
  `version` - the version at which to read from the database

#### addReadConflictRange

    void addReadConflictRange(byte[] keyBegin,
                              byte[] keyEnd)

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 this range could cause the transaction to fail with a conflict.

Parameters:
  `keyBegin` - the first key in the range (inclusive)
  `keyEnd` - the ending key for the range (exclusive)

#### addReadConflictKey

    void addReadConflictKey(byte[] key)

Adds a key to the transaction's read conflict ranges as if you had read the key. As a result, other transactions that concurrently write this key could cause the transaction to fail with a conflict.

Parameters:
  `key` - the key to be added to the range

#### addWriteConflictRange

    void addWriteConflictRange(byte[] keyBegin,
                               byte[] keyEnd)

Adds a range of keys to the transaction's write conflict ranges as if you had cleared the range. As a result, other transactions that concurrently read a key in this range could fail with a conflict.

Parameters:
  `keyBegin` - the first key in the range (inclusive)
  `keyEnd` - the ending key for the range (exclusive)

#### addWriteConflictKey

    void addWriteConflictKey(byte[] key)

Adds a key to the transaction's write conflict ranges as if you had written the key. As a result, other transactions that concurrently read this key could fail with a conflict.

Parameters:
  `key` - the key to be added to the range

#### set

    void set(byte[] key,
             byte[] value)

Sets the value for a given key. This will not affect the database until `commit()` is called.

Parameters:
  `key` - the key whose value is to be set
  `value` - the value to set in the database
Throws:
  `java.lang.IllegalArgumentException` - if `key` or `value` is `null`
  `FDBException` - if the set operation otherwise fails

#### clear

    void clear(byte[] key)

Clears a given key from the database. This will not affect the database until `commit()` is called.

Parameters:
  `key` - the key whose value is to be cleared
Throws:
  `java.lang.IllegalArgumentException` - if `key` is `null`
  `FDBException` - if clear operation otherwise fails

#### clear

    void clear(byte[] beginKey,
               byte[] endKey)

Clears a range of keys in the database. The upper bound of the range is exclusive; that is, the key (if one exists) that is specified as the end of the range will NOT be cleared as part of this operation. Range clears are efficient with FoundationDB -- clearing large amounts of data will be fast. This will not affect the database until `commit()` is called.

Parameters:
  `beginKey` - the first clear
  `endKey` - the key one past the last key to clear
Throws:
  `java.lang.IllegalArgumentException` - if `beginKey` or `endKey` is `null`
  `FDBException` - if the clear operation otherwise fails

#### clear

    void clear(Range range)

Clears a range of keys in the database. The upper bound of the range is exclusive; that is, the key (if one exists) that is specified as the end of the range will NOT be cleared as part of this operation. Range clears are efficient with FoundationDB -- clearing large amounts of data will be fast. This will not affect the database until `commit()` is called.

Parameters:
  `range` - the range of keys to clear
Throws:
  `FDBException` - if the clear operation fails

#### clearRangeStartsWith

    @Deprecated
    void clearRangeStartsWith(byte[] prefix)

Deprecated.
Replace with calls to `clear(Range)` with a parameter from a call to `Range.startsWith(byte[])`.

Parameters:
  `prefix` - the starting bytes from the keys to be cleared.
Throws:
  `FDBException` - if the clear-range operation fails

#### mutate

    void mutate(MutationType optype,
                byte[] key,
                byte[] param)

An atomic operation is a single database command that carries out several logical steps: reading the value of a key, performing a transformation on that value, and writing the result. Different atomic operations perform different transformations. Like other database operations, an atomic operation is used within a transaction.
Atomic operations do not expose the current value of the key to the client but simply send the database the transformation to apply. In regard to conflict checking, an atomic operation is equivalent to a write without a read. It can only cause other transactions performing reads of the key to conflict.
By combining these logical steps into a single, read-free operation, FoundationDB can guarantee that the transaction will not conflict due to the operation. This makes atomic operations ideal for operating on keys that are frequently modified. A common example is the use of a key-value pair as a counter.
Note: If a transaction uses both an atomic operation and a serializable read on the same key, the benefits of using the atomic operation (for both conflict checking and performance) are lost. The behavior of each `MutationType` is documented at its definition.

Parameters:
  `optype` - the operation to perform
  `key` - the target of the operation
  `param` - the value with which to modify the key

#### commit

    java.util.concurrent.CompletableFuture<java.lang.Void> commit()

Commit this `Transaction`. See notes in class description. Consider using `Database`'s `run()` calls for managing transactional access to FoundationDB.

As with other client/server databases, in some failure scenarios a client may be unable to determine whether a transaction succeeded. In these cases, an `FDBException` will be thrown with error code `commit_unknown_result` (1021). The `onError(java.lang.Throwable)` function regards this exception as a retryable one, so retry loops that don't specifically detect `commit_unknown_result` could end up executing a transaction twice. For more information, see the FoundationDB Developer Guide documentation.

If any operation is performed on a transaction after a commit has been issued but before it has returned, both the commit and the operation will throw an error code `used_during_commit` (2017). In this case, all subsequent operations on this transaction will throw this error.

Returns:
  a `CompletableFuture` that, when set without error, guarantees the `Transaction`'s modifications committed durably to the database. If the commit failed, it will throw an `FDBException`.

#### getCommittedVersion

    java.lang.Long getCommittedVersion()

Gets the version number at which a successful commit modified the database. This must be called only after the successful (non-error) completion of a call to `commit()` on this `Transaction`, or the behavior is undefined. Read-only transactions do not modify the database when committed and will have a committed version of -1. Keep in mind that a transaction which reads keys and then sets them to their current values may be optimized to a read-only transaction.

Returns:
  the database version at which the commit succeeded

#### getVersionstamp

    java.util.concurrent.CompletableFuture<byte[]> getVersionstamp()

Returns a future which will contain the versionstamp which was used by any versionstamp operations in this transaction. The future will be ready only after the successful completion of a call to `commit()` on this `Transaction`. Read-only transactions do not modify the database when committed and will result in the future completing with an error. Keep in mind that a transaction which reads keys and then sets them to their current values may be optimized to a read-only transaction.

Returns:
  a future containing the versionstamp which was used for any versionstamp operations in this transaction

#### onError

    java.util.concurrent.CompletableFuture<Transaction> onError(java.lang.Throwable e)

Resets a transaction and returns a delayed signal for error recovery. If the error encountered by the `Transaction` could not be recovered from, the returned `CompletableFuture` will be set to an error state. The current `Transaction` object will be invalidated by this call and will throw errors when used. The newly reset `Transaction` will be returned through the `CompletableFuture` if the error was retryable. If the error is not retryable, then no reset `Transaction` is returned, leaving this `Transaction` permanently invalidated.

Parameters:
  `e` - the error caught while executing get()s and set()s on this `Transaction`
Returns:
  a `CompletableFuture` to be set with a reset `Transaction` object to retry the transaction

#### cancel

    void cancel()

Cancels the `Transaction`. All pending and any future uses of the `Transaction` will throw an `RuntimeException`.

#### watch

    java.util.concurrent.CompletableFuture<java.lang.Void> watch(byte[] key)
                                                          throws FDBException

Creates a watch that will become ready when it reports a change to the value of the specified key.
A watch's behavior is relative to the transaction that created it. A watch will report a change in relation to the key's value as readable by that transaction. The initial value used for comparison is either that of the transaction's read version or the value as modified by the transaction itself prior to the creation of the watch. If the value changes and then changes back to its initial value, the watch might not report the change.
Until the transaction that created it has been committed, a watch will not report changes made by other transactions. In contrast, a watch will immediately report changes made by the transaction itself. Watches cannot be created if the transaction has set `TransactionOptions.setReadYourWritesDisable()`, and an attempt to do so will raise a `watches_disabled` exception.
If the transaction used to create a watch encounters an exception during commit, then the watch will be set with that exception. A transaction whose commit result is unknown will set all of its watches with the `commit_unknown_result` exception. If an uncommitted transaction is reset via `onError(java.lang.Throwable)` or destroyed, then any watches it created will be set with the `transaction_cancelled` exception.
By default, each database connection can have no more than 10,000 watches that have not yet reported a change. When this number is exceeded, an attempt to create a watch will raise a `too_many_watches` exception. Because a watch outlives the transaction that creates it, any watch that is no longer needed should be cancelled.
NOTE: calling code must call `commit()` for the watch to be registered with the database.

Parameters:
  `key` - the key to watch for changes in value
Returns:
  a `CompletableFuture` that will become ready when the value changes
Throws:
  `FDBException` - if too many watches have been created on this database. The limit defaults to 10,000 and can be modified with a call to `DatabaseOptions.setMaxWatches(long)`.

#### getDatabase

    Database getDatabase()

Returns the `Database` that this `Transaction` is interacting with.

Returns:
  the `Database` object

#### run

    <T> T run(java.util.function.Function<? super Transaction,T> retryable)

Run a function once against this `Transaction`. This call blocks while user code is executing, returning the result of that code on completion.

Specified by:
  `run` in interface `TransactionContext`
Type Parameters:
  `T` - the return type of `retryable`
Parameters:
  `retryable` - the block of logic to execute against this `Transaction`
Returns:
  a result of the single call to `retryable`

#### runAsync

    <T> java.util.concurrent.CompletableFuture<T> runAsync(java.util.function.Function<? super Transaction,? extends java.util.concurrent.CompletableFuture<T>> retryable)

Run a function once against this `Transaction`. This call returns immediately with a `CompletableFuture` handle to the result.

Specified by:
  `runAsync` in interface `TransactionContext`
Type Parameters:
  `T` - the return type of `retryable`
Parameters:
  `retryable` - the block of logic to execute against this `Transaction`
Returns:
  a `CompletableFuture` that will be set to the return value of `retryable`

#### close

    void close()

Close the `Transaction` object and release any associated resources. This must be called at least once after the `Transaction` object is no longer in use. This can be called multiple times, but care should be taken that it is not in use in another thread at the time of the call.

Specified by:
  `close` in interface `java.lang.AutoCloseable`