> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactions

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

CockroachDB supports bundling multiple SQL statements into a single all-or-nothing transaction. Each transaction guarantees [ACID semantics](https://en.wikipedia.org/wiki/ACID) spanning arbitrary tables and rows, even when data is distributed. If a transaction succeeds, all mutations are applied together with virtual simultaneity. If any part of a transaction fails, the entire transaction is aborted, and the database is left unchanged. By default, CockroachDB guarantees that while a transaction is pending, it is isolated from other concurrent transactions with `SERIALIZABLE` [isolation](#isolation-levels).

For a detailed discussion of CockroachDB transaction semantics, see [How CockroachDB Does Distributed Atomic Transactions](https://www.cockroachlabs.com/blog/how-cockroachdb-distributes-atomic-transactions/) and [Serializable, Lockless, Distributed: Isolation in CockroachDB](https://www.cockroachlabs.com/blog/serializable-lockless-distributed-isolation-cockroachdb/). The explanation of the transaction model described in this blog post is slightly out of date. See the [Transaction Retries](#transaction-retries) section for more details.

## SQL statements

The following SQL statements control transactions.

| Statement                                                                        | Description                                                                                                                                                                                          |
| -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <InternalLink path="begin-transaction">`BEGIN`</InternalLink>                    | Initiate a transaction and optionally set its [priority](#transaction-priorities), access mode, "as of" timestamp, or [isolation level](#isolation-levels).                                          |
| <InternalLink path="commit-transaction">`COMMIT`</InternalLink>                  | Commit a regular transaction, or clear the connection after committing a transaction using the <InternalLink path="advanced-client-side-transaction-retries">advanced retry protocol</InternalLink>. |
| <InternalLink path="release-savepoint">`RELEASE SAVEPOINT`</InternalLink>        | Commit a [nested transaction](#nested-transactions); also used for <InternalLink path="advanced-client-side-transaction-retries">retryable transactions</InternalLink>.                              |
| <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink>              | Abort a transaction and roll the database back to its state before the transaction began.                                                                                                            |
| <InternalLink path="rollback-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> | Roll back a [nested transaction](#nested-transactions); also used to handle <InternalLink path="advanced-client-side-transaction-retries">retryable transaction errors</InternalLink>.               |
| <InternalLink path="savepoint">`SAVEPOINT`</InternalLink>                        | Used for [nested transactions](#nested-transactions); also used to implement <InternalLink path="advanced-client-side-transaction-retries">advanced client-side transaction retries</InternalLink>.  |
| <InternalLink path="set-transaction">`SET TRANSACTION`</InternalLink>            | Set a transaction's [priority](#transaction-priorities), access mode, "as of" timestamp, or [isolation level](#isolation-levels).                                                                    |
| <InternalLink path="show-vars">`SHOW`</InternalLink>                             | Display the current transaction settings.                                                                                                                                                            |

<Note>
  If you are using a framework or library that does not have <InternalLink path="advanced-client-side-transaction-retries">advanced retry logic</InternalLink> built in, you should implement an application-level retry loop with exponential backoff. See <InternalLink path="transaction-retry-error-reference#client-side-retry-handling">Client-side retry handling</InternalLink>.
</Note>

## Syntax

In CockroachDB, a transaction is set up by surrounding SQL statements with the <InternalLink path="begin-transaction">`BEGIN`</InternalLink> and <InternalLink path="commit-transaction">`COMMIT`</InternalLink> statements.

To use <InternalLink path="advanced-client-side-transaction-retries">advanced client-side transaction retries</InternalLink>, you should also include the <InternalLink path="savepoint">`SAVEPOINT`</InternalLink>, <InternalLink path="rollback-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> and <InternalLink path="release-savepoint">`RELEASE SAVEPOINT`</InternalLink> statements.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> BEGIN;

> SAVEPOINT cockroach_restart;

<transaction statements>

> RELEASE SAVEPOINT cockroach_restart;

> COMMIT;
```

At any time before it's committed, you can abort the transaction by executing the <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink> statement.

Clients using transactions must also include logic to handle [retries](#transaction-retries).

## Error handling

To handle errors in transactions, you should check for the following types of server-side errors:

| Type                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Transaction Retry Errors** | Errors with the code `40001` and string `restart transaction`, which indicate that a transaction failed because it could not be placed in a <InternalLink path="demo-serializable">serializable ordering</InternalLink> of transactions by CockroachDB. This occurs under <InternalLink path="demo-serializable">`SERIALIZABLE`</InternalLink> isolation and only rarely under <InternalLink path="read-committed">`READ COMMITTED`</InternalLink> isolation. For details on transaction retry errors and how to resolve them, see the <InternalLink path="transaction-retry-error-reference#actions-to-take">Transaction Retry Error Reference</InternalLink>. |
| **Ambiguous Errors**         | Errors with the code `40003` which indicate that the state of the transaction is ambiguous, i.e., you cannot assume it either committed or failed. How you handle these errors depends on how you want to resolve the ambiguity. For information about how to handle ambiguous errors, see <InternalLink path="common-errors#result-is-ambiguous">here</InternalLink>.                                                                                                                                                                                                                                                                                          |
| **SQL Errors**               | All other errors, which indicate that a statement in the transaction failed. For example, violating the `UNIQUE` constraint generates a `23505` error. After encountering these errors, you can either issue a <InternalLink path="commit-transaction">`COMMIT`</InternalLink> or <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink> to abort the transaction and revert the database to its state before the transaction began.<br /><br />If you want to attempt the same set of statements again, you must begin a completely new transaction.                                                                                              |

## Transaction retries

Transactions may require retries due to <InternalLink path="performance-best-practices-overview">contention</InternalLink> with another concurrent or recent transaction attempting to write to the same data.

There are two cases in which transaction retries can occur:

* [Automatic retries](#automatic-retries), which CockroachDB silently processes for you.
* <InternalLink path="transaction-retry-error-reference#client-side-retry-handling">Client-side retries</InternalLink>, which your application must handle after receiving a <InternalLink path="transaction-retry-error-reference">*transaction retry error*</InternalLink> under `SERIALIZABLE` isolation. Client-side retry handling is not necessary for <InternalLink path="read-committed">`READ COMMITTED`</InternalLink> transactions.

To reduce the need for transaction retries, see <InternalLink path="performance-best-practices-overview#reduce-transaction-contention">Reduce transaction contention</InternalLink>.

### Automatic retries

CockroachDB automatically retries individual statements (implicit transactions) and [transactions sent from the client as a single batch](#batched-statements), as long as the size of the results being produced for the client, including protocol overhead, is less than 16KiB by default. Once that buffer overflows, CockroachDB starts streaming results back to the client, at which point automatic retries cannot be performed any more. As long as the results of a single statement or batch of statements are known to stay clear of this limit, the client does not need to worry about transaction retries.

You can increase the occurrence of automatic retries as a way to <InternalLink path="transaction-retry-error-reference#minimize-transaction-retry-errors">minimize transaction retry errors</InternalLink>:

* <InternalLink path="transactions#batched-statements">Send statements in transactions as a single batch</InternalLink>. Batching allows CockroachDB to <InternalLink path="transactions#automatic-retries">automatically retry</InternalLink> a transaction when <InternalLink path="architecture/transaction-layer#read-refreshing">previous reads are invalidated</InternalLink> at a <InternalLink path="architecture/transaction-layer#timestamp-cache">pushed timestamp</InternalLink>. When a multi-statement transaction is not batched, and takes more than a single round trip, CockroachDB cannot automatically retry the transaction. For an example showing how to break up large transactions in an application, see <InternalLink path="build-a-python-app-with-cockroachdb-sqlalchemy#break-up-large-transactions-into-smaller-units-of-work">Break up large transactions into smaller units of work</InternalLink>.

<a id="result-buffer-size" />

* Limit the size of the result sets of your transactions to less than the value of the <InternalLink path="cluster-settings">`sql.defaults.results_buffer.size` cluster setting</InternalLink>, so that CockroachDB is more likely to <InternalLink path="transactions#automatic-retries">automatically retry</InternalLink> when <InternalLink path="architecture/transaction-layer#read-refreshing">previous reads are invalidated</InternalLink> at a <InternalLink path="architecture/transaction-layer#timestamp-cache">pushed timestamp</InternalLink>. When a transaction returns a result set larger than the configured buffer size, even if that transaction has been sent as a single batch, CockroachDB cannot automatically retry the transaction. You can change the results buffer size for all new sessions using the <InternalLink path="cluster-settings">`sql.defaults.results_buffer.size` cluster setting</InternalLink>, or for a specific session using the `results_buffer_size` <InternalLink path="connection-parameters#additional-connection-parameters">connection parameter</InternalLink>.

<Note>
  Use <InternalLink path="alter-role#set-default-session-variable-values-for-all-users">`ALTER ROLE ALL SET {sessionvar} = {val}`</InternalLink> instead of the `sql.defaults.*` <InternalLink path="cluster-settings">cluster settings</InternalLink>. This allows you to set a default value for all users for any <InternalLink path="set-vars">session variable</InternalLink> that applies during login, making the `sql.defaults.*` cluster settings redundant.
</Note>

#### Individual statements

Individual statements are treated as implicit transactions, and so they fall
under the rules described above. If the results are small enough, they will be
automatically retried. In particular, `INSERT/UPDATE/DELETE` statements without
a `RETURNING` clause are guaranteed to have minuscule result sizes.
For example, the following statement would be automatically retried by CockroachDB:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> DELETE FROM customers WHERE id = 1;
```

#### Batched statements

Transactions can be sent from the client as a single batch. Batching implies that CockroachDB receives multiple statements without being asked to return results in between them; instead, CockroachDB returns results after executing all of the statements, except when the accumulated results overflow the buffer mentioned above, in which case they are returned sooner and automatic retries can no longer be performed.

Batching is generally controlled by your driver or client's behavior. Technically, it can be achieved in two ways, both supporting automatic retries:

1. When the client/driver is using the [PostgreSQL Extended Query protocol](https://www.postgresql.org/docs/10/static/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY), a batch is made up of all queries sent in between two `Sync` messages. Many drivers support such batches through explicit batching constructs.

2. When the client/driver is using the [PostgreSQL Simple Query protocol](https://www.postgresql.org/docs/10/static/protocol-flow.html#id-1.10.5.7.4), a batch is made up of semicolon-separated strings sent as a unit to CockroachDB. For example, in Go, this code would send a single batch (which would be automatically retried):

   ```go theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   db.Exec(
     "BEGIN;

     DELETE FROM customers WHERE id = 1;

     DELETE orders WHERE customer = 1;

     COMMIT;"
   )
   ```

Within a batch of statements, CockroachDB infers that the statements are not
conditional on the results of previous statements, so it can retry all of them.
Of course, if the transaction relies on conditional logic (e.g., statement 2 is
executed only for some results of statement 1), then the transaction cannot be
all sent to CockroachDB as a single batch. In these common cases, CockroachDB
cannot retry, say, statement 2 in isolation. Since results for statement 1 have
already been delivered to the client by the time statement 2 is forcing the
transaction to retry, the client needs to be involved in retrying the whole
transaction and so you should write your transactions to use
<InternalLink path="transaction-retry-error-reference#client-side-retry-handling">client-side retry handling</InternalLink>.

The <InternalLink path="set-vars">`enable_implicit_transaction_for_batch_statements` session variable</InternalLink> defaults to `true`. This means that any batch of statements is treated as an implicit transaction, so the `BEGIN`/`COMMIT` commands are not needed to group all the statements in one transaction.

#### Bounded staleness reads

In the event <InternalLink path="follower-reads#bounded-staleness-reads">bounded staleness reads</InternalLink> are used along with either the <InternalLink path="functions-and-operators">`with_min_timestamp` function or the `with_max_staleness` function</InternalLink> and the `nearest_only` parameter is set to `true`, the query will throw an error if it can't be served by a nearby replica.

## Nested transactions

CockroachDB supports the nesting of transactions using <InternalLink path="savepoint">savepoints</InternalLink>.  These nested transactions are also known as sub-transactions.  Nested transactions can be rolled back without discarding the state of the entire surrounding transaction.

This can be useful in applications that abstract database access using an application development framework or <InternalLink path="install-client-drivers">ORM</InternalLink>.  Different components of the application can operate on different sub-transactions without having to know about each others' internal operations, while trusting that the database will maintain isolation between sub-transactions and preserve data integrity.

Just as <InternalLink path="commit-transaction">`COMMIT`</InternalLink> and <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink> are used to commit and discard entire transactions, respectively, <InternalLink path="release-savepoint">`RELEASE SAVEPOINT`</InternalLink> and <InternalLink path="rollback-transaction#rollback-a-nested-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> are used to commit and discard nested transactions.  This relationship is shown in the following table:

| Statement                                                                                                      | Effect                                                |
| -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| <InternalLink path="commit-transaction">`COMMIT`</InternalLink>                                                | Commit an entire transaction.                         |
| <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink>                                            | Discard an entire transaction.                        |
| <InternalLink path="release-savepoint">`RELEASE SAVEPOINT`</InternalLink>                                      | Commit (really, forget) the named nested transaction. |
| <InternalLink path="rollback-transaction#rollback-a-nested-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> | Discard the changes in the named nested transaction.  |

For more information, including examples showing how to use savepoints to create nested transactions, see <InternalLink path="savepoint#examples">the savepoints documentation</InternalLink>.

## Transaction priorities

Every transaction in CockroachDB is assigned an initial **priority**. By default, the transaction priority is `NORMAL`.

### Set transaction priority

Cockroach Labs recommends leaving the transaction priority at the default setting in almost all cases. Changing the transaction priority to `HIGH` in particular can lead to difficult-to-debug interactions with other transactions executing on the system.

If you are setting a transaction priority to avoid <InternalLink path="performance-best-practices-overview#transaction-contention">contention</InternalLink> or <InternalLink path="understand-hotspots">hotspots</InternalLink>, or to <InternalLink path="make-queries-fast">get better query performance</InternalLink>, it is usually a sign that you need to update your schema design and/or review the data access patterns of your workload.

For transactions that you are absolutely sure should be given higher or lower priority, you can set the priority in the <InternalLink path="begin-transaction">`BEGIN`</InternalLink> statement:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> BEGIN PRIORITY <LOW | NORMAL | HIGH>;
```

You can also set the priority immediately after a transaction is started:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SET TRANSACTION PRIORITY <LOW | NORMAL | HIGH>;
```

To set the default transaction priority for all transactions in a session, use the `default_transaction_priority` <InternalLink path="set-vars">session variable</InternalLink>. For example:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SET default_transaction_priority = 'low';
```

### View transaction priority

`transaction_priority` is a read-only <InternalLink path="show-vars">session variable</InternalLink>.

To view the current priority of a transaction, use `SHOW transaction_priority` or <InternalLink path="show-vars">`SHOW TRANSACTION PRIORITY`</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SHOW transaction_priority;
```

```
  transaction_priority
------------------------
  low
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SHOW TRANSACTION PRIORITY;
```

```
  transaction_priority
------------------------
  low
```

## Isolation levels

Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: <InternalLink path="demo-serializable">`SERIALIZABLE`</InternalLink> and <InternalLink path="read-committed">`READ COMMITTED`</InternalLink>.

By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require <InternalLink path="transaction-retry-error-reference">transaction restarts</InternalLink> and <InternalLink path="transaction-retry-error-reference#client-side-retry-handling">client-side retry handling</InternalLink>. For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to <InternalLink path="demo-serializable">Serializable Transactions</InternalLink>.

`READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, refer to <InternalLink path="read-committed">Read Committed Transactions</InternalLink>.

### Mixed isolation levels#### Mixed isolation levels

Regardless of the isolation levels of other transactions, transactions behave according to their respective isolation levels: Statements in `SERIALIZABLE` transactions see data that committed before the transaction began, whereas statements in `READ COMMITTED` transactions see data that committed before each **statement** began. Therefore:

* If a `READ COMMITTED` transaction `R` commits before a `SERIALIZABLE` transaction `S`, every statement in `S` will observe all writes from `R`. Otherwise, `S` will not observe any writes from `R`.
* If a `SERIALIZABLE` transaction `S` commits before a `READ COMMITTED` transaction `R`, every **subsequent** statement in `R` will observe all writes from `S`. Otherwise, `R` will not observe any writes from `S`.

However, there is one difference in how `SERIALIZABLE` writes affect non-locking reads: While writes in a `SERIALIZABLE` transaction can block reads in concurrent `SERIALIZABLE` transactions, they will **not** block reads in concurrent `READ COMMITTED` transactions. Writes in a `READ COMMITTED` transaction will never block reads in concurrent transactions, regardless of their isolation levels. Therefore:

* If a `READ COMMITTED` transaction `R` writes but does not commit before a `SERIALIZABLE` transaction `S`, no statement in `S` will observe or be blocked by any uncommitted writes from `R`.
* If a `SERIALIZABLE` transaction `S` writes but does not commit before a `READ COMMITTED` transaction `R`, no statement in `R` will observe or be blocked by any uncommitted writes from `S`.
* If a `SERIALIZABLE` transaction `S1` writes but does not commit before a `SERIALIZABLE` transaction `S2`, the first statement in `S2` that would observe an unwritten row from `S1` will be blocked until `S1` commits or aborts.

### Isolation level upgrades

By default, CockroachDB executes all transactions at `SERIALIZABLE` isolation. Under certain conditions, transactions issued at weaker isolation levels are automatically upgraded to stronger isolation levels.

* If `sql.txn.read_committed_isolation.enabled` is set to `true` (<InternalLink path="read-committed#enable-read-committed-isolation">enabling `READ COMMITTED` isolation</InternalLink>), `READ UNCOMMITTED` transactions are upgraded to `READ COMMITTED` isolation.

* If `sql.txn.read_committed_isolation.enabled` is set to `false` (disabling `READ COMMITTED` isolation), all transactions are upgraded to `SERIALIZABLE` isolation regardless of the isolation level requested.

### Comparison to ANSI SQL isolation levels

CockroachDB uses slightly different isolation levels than [ANSI SQL isolation levels](https://wikipedia.org/wiki/Isolation_\(database_systems\)#Isolation_levels).

The CockroachDB `SERIALIZABLE` isolation level is stronger than the ANSI SQL `READ UNCOMMITTED`, `READ COMMITTED`, and `REPEATABLE READ` levels, as well as the `SNAPSHOT` level. It is equivalent to the ANSI SQL `SERIALIZABLE` level.

The CockroachDB `READ COMMITTED` isolation level is stronger than the PostgreSQL `READ COMMITTED` isolation level, and is the strongest isolation level that does not experience <InternalLink path="transaction-retry-error-reference">serialization errors</InternalLink> that require <InternalLink path="transaction-retry-error-reference#client-side-retry-handling">client-side handling</InternalLink>.

For more information about the relationship between these levels, read [A Critique of ANSI SQL Isolation Levels](https://arxiv.org/ftp/cs/papers/0701/0701157.pdf).

## Limit the number of rows written or read in a transaction

You can limit the number of rows written or read in a transaction at the cluster or session level. This allows you configure CockroachDB to log or reject statements that could destabilize a cluster or violate application best practices.

* When the `transaction_rows_read_err` <InternalLink path="set-vars">session setting</InternalLink> is enabled, transactions that read more than the specified number of rows will fail. In addition, the <InternalLink path="cost-based-optimizer">optimizer</InternalLink> will not create query plans with scans that exceed the specified row limit. For example, to set a default value for <InternalLink path="alter-role#set-default-session-variable-values-for-all-users">all users</InternalLink> at the cluster level:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER ROLE ALL SET transaction_rows_read_err = 1000;
  ```

* When the `transaction_rows_written_err` <InternalLink path="set-vars">session setting</InternalLink> is enabled, transactions that write more than the specified number of rows will fail. For example, to set a default value for all users at the cluster level:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER ROLE ALL SET transaction_rows_written_err = 1000;
  ```

To assess the impact of configuring these session settings, use the corresponding session settings <InternalLink path="set-vars">`transaction_rows_read_log`</InternalLink> and <InternalLink path="set-vars">`transaction_rows_written_log`</InternalLink> to log transactions that read or write the specified number of rows. Transactions are logged to the <InternalLink path="logging#sql_perf">`SQL_PERF`</InternalLink> channel.

The limits are enforced after each statement of a transaction has been fully executed. The "write" limits apply to `INSERT`, `INSERT INTO SELECT FROM`, `INSERT ON CONFLICT`, `UPSERT`, `UPDATE`, and `DELETE` SQL statements. The "read" limits apply to the `SELECT` statement in addition to the statements subject to the "write" limits. The limits **do not** apply to `CREATE TABLE AS`, `IMPORT`, `TRUNCATE`, `DROP`, `ALTER TABLE`, `BACKUP`, `RESTORE`, or `CREATE STATISTICS` statements.

<Note>
  Enabling `transaction_rows_read_err` disables a performance optimization for mutation statements in implicit transactions where CockroachDB can auto-commit without additional network round trips.
</Note>

<a id="cost-based-optimizer-kl" />

## Known limitations

* The `transaction_rows_read_err` and `transaction_rows_written_err` <InternalLink path="set-vars">session settings</InternalLink> limit the number of rows read or written by a single <InternalLink path="transactions#limit-the-number-of-rows-written-or-read-in-a-transaction">transaction</InternalLink>. These session settings will fail the transaction with an error, but not until the current query finishes executing and the results have been returned to the client.

## See also

* <InternalLink path="begin-transaction">`BEGIN`</InternalLink>
* <InternalLink path="commit-transaction">`COMMIT`</InternalLink>
* <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink>
* <InternalLink path="savepoint">`SAVEPOINT`</InternalLink>
* <InternalLink path="release-savepoint">`RELEASE SAVEPOINT`</InternalLink>
* <InternalLink path="show-vars">`SHOW`</InternalLink>
* <InternalLink path="build-a-java-app-with-cockroachdb">Retryable transaction example code in Java using JDBC</InternalLink>
* <InternalLink path="ui-transactions-page">DB Console Transactions Page</InternalLink>
* <InternalLink path="architecture/transaction-layer">CockroachDB Architecture: Transaction Layer</InternalLink>
* <InternalLink path="transaction-retry-error-reference">Transaction retry error reference</InternalLink>
