run

suspend fun <V> run(timeout: Duration? = null, parentSpan: RequestSpan? = null, durability: Durability? = null, metadataCollection: Keyspace? = null, transactionLogic: suspend TransactionAttemptContext.() -> V): TransactionResult<V>

Runs supplied transactional logic until success or failure.

The supplied transactional logic will be run if necessary multiple times, until either:

  • The transaction successfully commits

  • The transactional logic requests an explicit rollback

  • The transaction times out.

  • An exception is thrown, either inside the transaction library or by the supplied transaction logic, that cannot be handled.

The transaction logic {@link Consumer} is provided an {@link TransactionAttemptContext}, which contains methods allowing it to read, mutate, insert and delete documents, as well as commit or rollback the transaction.

If the transaction logic performs a commit or rollback it must be the last operation performed. Else a TransactionFailedException will be thrown. Similarly, there cannot be a commit followed by a rollback, or vice versa - this will also raise a TransactionFailedException.

If the transaction logic does not perform an explicit commit or rollback, then a commit will be performed anyway.

Return

The value returned by the transaction logic, along with diagnostic information.

Samples

import com.couchbase.client.kotlin.Cluster
import com.couchbase.client.kotlin.Collection
import com.couchbase.client.kotlin.transactions.TransactionGetResult
import kotlin.random.Random
fun main() { 
   //sampleStart 
   // Assume two documents both contain integers.
// Subtract a value from the one document and add it to the other.
cluster.transactions.run {
    // The SDK may execute this lambda multiple times
    // if there are conflicts between transactions.
    // All logic related to the transaction must happen
    // inside this lambda.

    // Inside the lambda, `this` is a `TransactionAttemptContext`
    // with instance methods like `get`, `replace`, `insert`, `remove`,
    // and `query` for interacting with documents in a transactional way.
    // These are the only methods you should use to interact with documents
    // inside the transaction lambda.

    val source: TransactionGetResult = get(collection, sourceDocId)
    val dest: TransactionGetResult = get(collection, destDocId)

    val newSourceValue: Int = source.contentAs<Int>() - value
    val newDestValue: Int = dest.contentAs<Int>() + value

    replace(source, newSourceValue)

    // Throwing any exception triggers a rollback and causes
    // `transactions.run` to throw TransactionFailedException.
    if (Random.nextBoolean()) throw RuntimeException("simulated error")
    require(newSourceValue >= 0) { "transfer would result in negative source value" }
    require(newDestValue >= 0) { "transfer would result in dest value overflow" }

    replace(dest, newDestValue)
} 
   //sampleEnd
}

Parameters

durability

Durability level for this transaction, or null to use the cluster environment's default transaction durability. Must not be Durability.none or Durability.clientVerified, which are not compatible with transactions.

timeout

Time allowed for this transaction to complete, or null to use the cluster environment's default timeout duration.

metadataCollection

The location in Couchbase to store metadata this transaction, or null to use the cluster environment's default metadata collection.

Throws

or a derived exception if the transaction fails to commit for any reason, possibly after multiple retries. The exception contains further details of the error