> ## 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.

# RELEASE SAVEPOINT

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>;
};

The `RELEASE SAVEPOINT` statement commits the <InternalLink path="transactions#nested-transactions">nested transaction</InternalLink> starting at the corresponding `SAVEPOINT` statement using the same savepoint name, including all its nested sub-transactions. This is in addition to continued support for working with <InternalLink path="savepoint#savepoints-for-client-side-transaction-retries">retry savepoints</InternalLink>.

## Synopsis

<img src="https://mintcdn.com/cockroachlabs/URZZsrJ2y-tKyo7i/images/sql-diagrams/v24.3/release_savepoint.svg?fit=max&auto=format&n=URZZsrJ2y-tKyo7i&q=85&s=845ad7dbb1b1d8f93a14b1a435dc330a" alt="release_savepoint syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="375" height="69" data-path="images/sql-diagrams/v24.3/release_savepoint.svg" />

## Required privileges

No <InternalLink path="security-reference/authorization#managing-privileges">privileges</InternalLink> are required to release a savepoint. However, privileges are required for each statement within a transaction.

## Parameters

| Parameter | Description                                                                                                                                                                                                                                                                                                                                                                                      |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name      | The name of the savepoint. <InternalLink path="savepoint#savepoints-for-client-side-transaction-retries">Retry savepoints</InternalLink> default to using the name `cockroach\_restart`, but this can be customized using a session variable. For more information, see <InternalLink path="savepoint#customizing-the-retry-savepoint-name">Customizing the retry savepoint name</InternalLink>. |

## Handling errors

The `RELEASE SAVEPOINT` statement is invalid after the nested transaction has encountered an error. After an error, the following statements can be used:

* <InternalLink path="rollback-transaction#rollback-a-nested-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> to roll back to the previous savepoint.
* <InternalLink path="rollback-transaction#rollback-a-transaction">`ROLLBACK` or `ABORT`</InternalLink> to roll back the entire surrounding transaction.
* <InternalLink path="commit-transaction">`COMMIT`</InternalLink> to commit the entire surrounding transaction. In case of error, `COMMIT` is synonymous with <InternalLink path="rollback-transaction">`ROLLBACK`/`ABORT`</InternalLink> and also rolls back the entire transaction.

When a (sub-)transaction encounters a retry error, the client should repeat `ROLLBACK TO SAVEPOINT` and the statements in the transaction until the statements complete without error, then issue `RELEASE`.

To completely remove the marker of a nested transaction after it encounters an error and begin other work in the outer transaction, use <InternalLink path="rollback-transaction#rollback-a-nested-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink> immediately followed by `RELEASE`.

## Examples

### Commit a nested transaction by releasing a savepoint

<Note>
  This example uses the <InternalLink path="movr">MovR data set</InternalLink>.
</Note>

In the example below, we roll back the inner <InternalLink path="transactions#nested-transactions">nested transaction</InternalLink> (marked by the savepoint `lower`) and release (commit) the outer savepoint `higher`, which raises the promo code discount to 15% using CockroachDB's <InternalLink path="jsonb#functions">JSONB functions</InternalLink>.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> BEGIN;
SAVEPOINT higher;
UPDATE promo_codes SET rules = jsonb_set(rules, '{value}', '"15%"') WHERE rules @> '{"type": "percent_discount"}';
SAVEPOINT lower;
UPDATE promo_codes SET rules = jsonb_set(rules, '{value}', '"7.5%"') WHERE rules @> '{"type": "percent_discount"}';
ROLLBACK TO SAVEPOINT lower;
RELEASE SAVEPOINT higher;
COMMIT;
```

```text theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
COMMIT
```

### Commit a transaction by releasing a retry savepoint

A savepoint defined with the name `cockroach_restart` is a "retry savepoint" and is used to implement <InternalLink path="advanced-client-side-transaction-retries">advanced client-side transaction retries</InternalLink>. For more information, see <InternalLink path="advanced-client-side-transaction-retries#retry-savepoints">Retry savepoints</InternalLink>.

After declaring a retry savepoint, commit the transaction with `RELEASE SAVEPOINT` and then prepare the connection for the next transaction with <InternalLink path="commit-transaction">`COMMIT`</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> BEGIN;
SAVEPOINT cockroach_restart;
UPDATE products SET inventory = 0 WHERE sku = '8675309';
INSERT INTO orders (customer, sku, status) VALUES (1001, '8675309', 'new');
RELEASE SAVEPOINT cockroach_restart;
COMMIT;
```

Applications using `SAVEPOINT` for client-side transaction retries must also include functions to execute retries with <InternalLink path="rollback-transaction#retry-a-transaction">`ROLLBACK TO SAVEPOINT`</InternalLink>.

Note that you can <InternalLink path="savepoint#customizing-the-retry-savepoint-name">customize the retry savepoint name</InternalLink> to something other than `cockroach_restart` with a session variable if you need to.

## See also

* <InternalLink path="transactions">Transactions</InternalLink>
* <InternalLink path="savepoint">`SAVEPOINT`</InternalLink>
* <InternalLink path="show-savepoint-status">`SHOW SAVEPOINT STATUS`</InternalLink>
* <InternalLink path="rollback-transaction">`ROLLBACK`</InternalLink>
* <InternalLink path="begin-transaction">`BEGIN`</InternalLink>
* <InternalLink path="commit-transaction">`COMMIT`</InternalLink>
