Skip to content

Commit

Permalink
Document nested SAVEPOINTs
Browse files Browse the repository at this point in the history
Fixes #5953.

Summary of changes:

- Update SAVEPOINT page with more examples of "generalized" aka "nested"
  savepoints adapted from the RFC, in addition to the existing "retry"
  savepoints info

- Add a new SHOW SAVEPOINT STATUS statement page (with syntax diagram),
  and add it to the sidebar

- Update RELEASE SAVEPOINT docs to clarify "retry" savepoints
  vs. "generalized", and update the example as well

- Update the ROLLBACK docs to mention rollbacks to savepoints more
  explicitly.  Also, update the diagram to reflect that
  'cockroach_restart' is no longer a special savepoint name.

- Update all 20.1 documentation to reflect that 'cockroach_restart' is
  no longer a special retry savepoint name, nor is it required.  As part
  of this, rename all savepoint examples using 'cockroach_restart' to
  use names like 'my_savepoint', etc.
  • Loading branch information
rmloveland committed Mar 12, 2020
1 parent 2a18c9a commit ba35ff3
Show file tree
Hide file tree
Showing 17 changed files with 393 additions and 99 deletions.
6 changes: 6 additions & 0 deletions _includes/sidebar-data-v20.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,12 @@
"/${VERSION}/show-statistics.html"
]
},
{
"title": "<code>SHOW SAVEPOINT STATUS</code>",
"urls": [
"/${VERSION}/show-savepoint-status.html"
]
},
{
"title": "<code>SHOW TABLES</code>",
"urls": [
Expand Down
7 changes: 0 additions & 7 deletions _includes/v20.1/misc/customizing-the-savepoint-name.md

This file was deleted.

3 changes: 0 additions & 3 deletions _includes/v20.1/misc/savepoint-limitations.md

This file was deleted.

39 changes: 17 additions & 22 deletions _includes/v20.1/sql/diagrams/rollback_transaction.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
<div><svg width="518" height="68">

<polygon points="9 17 1 13 1 21"></polygon>
<polygon points="17 17 9 13 9 21"></polygon>
<rect x="31" y="3" width="92" height="32" rx="10"></rect>
<rect x="29" y="1" width="92" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="39" y="21">ROLLBACK</text>
<rect x="163" y="35" width="38" height="32" rx="10"></rect>
<rect x="161" y="33" width="38" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="171" y="53">TO</text>
<rect x="221" y="35" width="98" height="32" rx="10"></rect>
<rect x="219" y="33" width="98" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="229" y="53">SAVEPOINT</text>

<rect x="339" y="35" width="132" height="32"></rect>
<rect x="337" y="33" width="132" height="32" class="nonterminal"></rect>
<text class="nonterminal" x="347" y="53">cockroach_restart</text>

<path class="line" d="m17 17 h2 m0 0 h10 m92 0 h10 m20 0 h10 m0 0 h318 m-348 0 h20 m328 0 h20 m-368 0 q10 0 10 10 m348 0 q0 -10 10 -10 m-358 10 v12 m348 0 v-12 m-348 12 q0 10 10 10 m328 0 q10 0 10 -10 m-338 10 h10 m38 0 h10 m0 0 h10 m98 0 h10 m0 0 h10 m132 0 h10 m23 -32 h-3"></path>
<polygon points="509 17 517 13 517 21"></polygon>
<polygon points="509 17 501 13 501 21"></polygon>
</svg></div>
<div><svg width="515" height="69">
<polygon points="9 17 1 13 1 21"></polygon>
<polygon points="17 17 9 13 9 21"></polygon>
<rect x="31" y="3" width="92" height="32" rx="10"></rect>
<rect x="29" y="1" width="92" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="39" y="21">ROLLBACK</text>
<rect x="163" y="35" width="38" height="32" rx="10"></rect>
<rect x="161" y="33" width="38" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="171" y="53">TO</text>
<rect x="221" y="35" width="100" height="32" rx="10"></rect>
<rect x="219" y="33" width="100" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="229" y="53">SAVEPOINT</text><a xlink:href="sql-grammar.html#savepoint_name" xlink:title="savepoint_name">
<rect x="341" y="35" width="126" height="32"></rect>
<rect x="339" y="33" width="126" height="32" class="nonterminal"></rect>
<text class="nonterminal" x="349" y="53">savepoint_name</text></a><path class="line" d="m17 17 h2 m0 0 h10 m92 0 h10 m20 0 h10 m0 0 h314 m-344 0 h20 m324 0 h20 m-364 0 q10 0 10 10 m344 0 q0 -10 10 -10 m-354 10 v12 m344 0 v-12 m-344 12 q0 10 10 10 m324 0 q10 0 10 -10 m-334 10 h10 m38 0 h10 m0 0 h10 m100 0 h10 m0 0 h10 m126 0 h10 m23 -32 h-3"></path>
<polygon points="505 17 513 13 513 21"></polygon>
<polygon points="505 17 497 13 497 21"></polygon></svg></div>
15 changes: 15 additions & 0 deletions _includes/v20.1/sql/diagrams/show_savepoint_status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div><svg width="335" height="37">
<polygon points="9 17 1 13 1 21"></polygon>
<polygon points="17 17 9 13 9 21"></polygon>
<rect x="31" y="3" width="64" height="32" rx="10"></rect>
<rect x="29" y="1" width="64" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="39" y="21">SHOW</text>
<rect x="115" y="3" width="100" height="32" rx="10"></rect>
<rect x="113" y="1" width="100" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="123" y="21">SAVEPOINT</text>
<rect x="235" y="3" width="72" height="32" rx="10"></rect>
<rect x="233" y="1" width="72" height="32" class="terminal" rx="10"></rect>
<text class="terminal" x="243" y="21">STATUS</text>
<path class="line" d="m17 17 h2 m0 0 h10 m64 0 h10 m0 0 h10 m100 0 h10 m0 0 h10 m72 0 h10 m3 0 h-3"></path>
<polygon points="325 17 333 13 333 21"></polygon>
<polygon points="325 17 317 13 317 21"></polygon></svg></div>
3 changes: 3 additions & 0 deletions _includes/v20.1/sql/savepoint-ddl-rollbacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{site.data.alerts.callout_danger}}
Rollbacks to savepoints over [DDL](https://en.wikipedia.org/wiki/Data_definition_language) statements are not yet supported. This is a known limitation and will be removed in a future version of CockroachDB.
{{site.data.alerts.end}}
10 changes: 3 additions & 7 deletions v20.1/advanced-client-side-transaction-retries.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ A retryable transaction goes through the process described below, which maps to
{% include copy-clipboard.html %}
~~~ sql
> BEGIN; -- #1
> SAVEPOINT cockroach_restart; -- #2
> SAVEPOINT retry_savepoint; -- #2
-- ... various transaction statements ... -- #3
> RELEASE SAVEPOINT cockroach_restart; -- #5 (Or #4, ROLLBACK, in case of retry error)
> RELEASE SAVEPOINT retry_savepoint; -- #5 (Or #4, ROLLBACK, in case of retry error)
> COMMIT;
~~~

1. The transaction starts with the [`BEGIN`](begin-transaction.html) statement.

2. The [`SAVEPOINT`](savepoint.html) statement declares the intention to retry the transaction in the case of contention errors. Note that CockroachDB's savepoint implementation does not support all savepoint functionality, such as nested transactions. It must be executed after [`BEGIN`](begin-transaction.html) but before the first statement that manipulates a database.
2. The [`SAVEPOINT`](savepoint.html) statement declares the intention to retry the transaction in the case of contention errors. It must be executed after [`BEGIN`](begin-transaction.html) but before the first statement that manipulates a database. In other words, it must be the outermost statement in an XXX: YOU ARE HERE.

3. The statements in the transaction are executed.

Expand All @@ -46,10 +46,6 @@ A retryable transaction goes through the process described below, which maps to

In some cases, the [`RELEASE SAVEPOINT`](release-savepoint.html) statement itself can fail with a retry error, mainly because transactions in CockroachDB only realize that they need to be restarted when they attempt to commit. If this happens, the retry error is handled as described in step 4.

## Customizing the savepoint name

{% include {{ page.version.version }}/misc/customizing-the-savepoint-name.md %}

## Examples

For examples showing how to use [`SAVEPOINT`](savepoint.html) and the other statements described on this page to implement library support for a programming language, see the following:
Expand Down
8 changes: 4 additions & 4 deletions v20.1/begin-transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Without modifying the `BEGIN` statement, the transaction uses `SERIALIZABLE` iso

{% include copy-clipboard.html %}
~~~ sql
> SAVEPOINT cockroach_restart;
> SAVEPOINT my_savepoint;
~~~

{% include copy-clipboard.html %}
Expand All @@ -68,7 +68,7 @@ Without modifying the `BEGIN` statement, the transaction uses `SERIALIZABLE` iso

{% include copy-clipboard.html %}
~~~ sql
> RELEASE SAVEPOINT cockroach_restart;
> RELEASE SAVEPOINT my_savepoint;
~~~

{% include copy-clipboard.html %}
Expand All @@ -89,7 +89,7 @@ You can set a transaction's priority to `LOW` or `HIGH`.

{% include copy-clipboard.html %}
~~~ sql
> SAVEPOINT cockroach_restart;
> SAVEPOINT my_savepoint;
~~~

{% include copy-clipboard.html %}
Expand All @@ -104,7 +104,7 @@ You can set a transaction's priority to `LOW` or `HIGH`.

{% include copy-clipboard.html %}
~~~ sql
> RELEASE SAVEPOINT cockroach_restart;
> RELEASE SAVEPOINT my_savepoint;
~~~

{% include copy-clipboard.html %}
Expand Down
5 changes: 3 additions & 2 deletions v20.1/commit-transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ When using [advanced client-side transaction retries](advanced-client-side-trans

{% include copy-clipboard.html %}
~~~ sql
> SAVEPOINT cockroach_restart;
> SAVEPOINT retry_savepoint;
~~~

{% include copy-clipboard.html %}
Expand All @@ -55,7 +55,7 @@ When using [advanced client-side transaction retries](advanced-client-side-trans

{% include copy-clipboard.html %}
~~~ sql
> RELEASE SAVEPOINT cockroach_restart;
> RELEASE SAVEPOINT retry_savepoint;
~~~

{% include copy-clipboard.html %}
Expand All @@ -81,3 +81,4 @@ If you are using transactions that CockroachDB will [automatically retry](transa
- [`RELEASE SAVEPOINT`](release-savepoint.html)
- [`ROLLBACK`](rollback-transaction.html)
- [`SAVEPOINT`](savepoint.html)
- [`SHOW SAVEPOINT STATUS`](show-savepoint-status.html)
4 changes: 2 additions & 2 deletions v20.1/follower-reads.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ BEGIN;

SET TRANSACTION AS OF SYSTEM TIME experimental_follower_read_timestamp();

SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;

SELECT ...
SELECT ...
Expand Down Expand Up @@ -102,7 +102,7 @@ To counteract this, you can issue all follower reads in explicit transactions se
```sql
BEGIN PRIORITY HIGH AS OF SYSTEM TIME experimental_follower_read_timestamp();

SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;

SELECT ...
SELECT ...
Expand Down
16 changes: 8 additions & 8 deletions v20.1/online-schema-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ However, as of version v2.1, you can run schema changes inside the same transact
{% include copy-clipboard.html %}
~~~ sql
> BEGIN;
SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;
CREATE TABLE fruits (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name STRING,
Expand All @@ -62,7 +62,7 @@ However, as of version v2.1, you can run schema changes inside the same transact
ALTER TABLE fruits ADD COLUMN inventory_count INTEGER DEFAULT 5;
ALTER TABLE fruits ADD CONSTRAINT name CHECK (name IN ('apple', 'banana', 'orange'));
SELECT name, color, inventory_count FROM fruits;
RELEASE SAVEPOINT cockroach_restart;
RELEASE SAVEPOINT my_savepoint;
COMMIT;
~~~

Expand Down Expand Up @@ -139,10 +139,10 @@ The following statements fail due to [limited support for schema changes within
~~~ sql
> CREATE TABLE foo (id INT PRIMARY KEY, name VARCHAR);
BEGIN;
SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;
CREATE INDEX foo_idx ON foo (id, name);
SELECT * from foo_idx;
RELEASE SAVEPOINT cockroach_restart;
RELEASE SAVEPOINT my_savepoint;
COMMIT;
~~~

Expand All @@ -162,10 +162,10 @@ ROLLBACK
~~~ sql
> CREATE TABLE foo ();
BEGIN;
SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;
ALTER TABLE foo ADD COLUMN bar VARCHAR;
ALTER TABLE foo ADD CONSTRAINT bar CHECK (foo IN ('a', 'b', 'c', 'd'));
RELEASE SAVEPOINT cockroach_restart;
RELEASE SAVEPOINT my_savepoint;
COMMIT;
~~~

Expand All @@ -185,10 +185,10 @@ ROLLBACK
~~~ sql
> CREATE TABLE foo ();
BEGIN;
SAVEPOINT cockroach_restart;
SAVEPOINT my_savepoint;
ALTER TABLE foo ADD COLUMN bar VARCHAR;
SELECT bar FROM foo;
RELEASE SAVEPOINT cockroach_restart;
RELEASE SAVEPOINT my_savepoint;
COMMIT;
~~~

Expand Down
36 changes: 13 additions & 23 deletions v20.1/release-savepoint.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
title: RELEASE SAVEPOINT
summary: Commit a transaction's changes once there are no retry errors with the RELEASE SAVEPOINT statement in CockroachDB.
summary: Commit a sub-transaction.
toc: true
---

When using [advanced client-side transaction retries](advanced-client-side-transaction-retries.html), the `RELEASE SAVEPOINT` statement commits the transaction.
The `RELEASE SAVEPOINT` statement commits the [sub-transaction](transactions.html#sub-transactions) starting at the corresponding `SAVEPOINT` statement using the same savepoint name, including all its nested sub-transactions.

If statements in the transaction [generated any non-retry errors](transactions.html#error-handling), `RELEASE SAVEPOINT` is equivalent to [`ROLLBACK`](rollback-transaction.html), which aborts the transaction and discards all updates made by its statements.
The `RELEASE SAVEPOINT` statement is invalid after the sub-transaction has encountered an error. After an error, the [`ROLLBACK TO SAVEPOINT`](rollback-transaction.html#using-rollbacks-with-nested-savepoints) statement must be used instead.

Note that although issuing this statement commits the transaction, you must also issue a subsequent [`COMMIT`](commit-transaction.html) statement to prepare the connection for the next 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`.

{% include {{ page.version.version }}/misc/savepoint-limitations.md %}
To completely remove the marker of a sub-transaction after it encounters an error and begin other work in the outer transaction, use [`ROLLBACK TO SAVEPOINT`](rollback-transaction.html#using-rollbacks-with-nested-savepoints) immediately followed by `RELEASE`.

## Synopsis

Expand All @@ -26,11 +26,7 @@ No [privileges](authorization.html#assign-privileges) are required to release a

Parameter | Description
--------- | -----------
name | The name of the savepoint. Defaults to `cockroach_restart`, but may be customized. For more information, see [Customizing the savepoint name](#customizing-the-savepoint-name).

## Customizing the savepoint name

{% include {{ page.version.version }}/misc/customizing-the-savepoint-name.md %}
name | The name of the savepoint.

## Examples

Expand All @@ -40,25 +36,19 @@ After declaring a [`SAVEPOINT`](savepoint.html), commit the transaction with `RE

{% include copy-clipboard.html %}
~~~ sql
> 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;
BEGIN;
SAVEPOINT update_inventory;
UPDATE products SET inventory = 0 WHERE sku = '8675309';
INSERT INTO orders (customer, sku, status) VALUES (1001, '8675309', 'new');
RELEASE SAVEPOINT update_inventory;
COMMIT;
~~~

{{site.data.alerts.callout_danger}}This example assumes you're using <a href="transactions.html#client-side-intervention">client-side intervention to handle transaction retries</a>.{{site.data.alerts.end}}

## See also

- [Transactions](transactions.html)
- [`SAVEPOINT`](savepoint.html)
- [`SHOW SAVEPOINT STATUS`](show-savepoint-status.html)
- [`ROLLBACK`](rollback-transaction.html)
- [`BEGIN`](begin-transaction.html)
- [`COMMIT`](commit-transaction.html)
21 changes: 16 additions & 5 deletions v20.1/rollback-transaction.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
---
title: ROLLBACK
summary: Abort the current transaction, discarding all updates made by statements included in the transaction with the ROLLBACK statement in CockroachDB.
summary: Rolls back the current transaction or sub-transaction, discarding all transactional updates made by statements inside the transaction.
toc: true
---

The `ROLLBACK` [statement](sql-statements.html) aborts the current [transaction](transactions.html), discarding all updates made by statements included in the transaction.
The `ROLLBACK` [statement](sql-statements.html) aborts the current [transaction](transactions.html) or [sub-transaction](transactions.html#sub-transactions), discarding all transactional updates made by statements included in the transaction.

The base `ROLLBACK` syntax [rolls back the entire transaction](#rollback-a-transaction).

The `ROLLBACK TO SAVEPOINT` syntax rolls back and restarts the [sub-transaction](transactions.html#sub-transactions) started at the corresponding `SAVEPOINT` statement. For more information, see [the documentation for `SAVEPOINT`](savepoint.html).

{% include {{page.version.version}}/sql/savepoint-ddl-rollbacks.md %}

When using [advanced client-side transaction retries](advanced-client-side-transaction-retries.html), use `ROLLBACK TO SAVEPOINT` to handle a transaction that needs to be retried (identified via the `40001` error code or `retry transaction` string in the error message), and then re-execute the statements you want the transaction to contain.

Expand All @@ -22,10 +28,14 @@ No [privileges](authorization.html#assign-privileges) are required to rollback a

Parameter | Description
-----------|-------------
`TO SAVEPOINT cockroach_restart` | If using [advanced client-side transaction retries](advanced-client-side-transaction-retries.html), retry the transaction. You should execute this statement when a transaction returns a `40001` / `retry transaction` error.
`TO SAVEPOINT <name>` | If using [advanced client-side transaction retries](advanced-client-side-transaction-retries.html), retry the transaction. You should execute this statement when a transaction returns a `40001` / `retry transaction` error.

## Example

### Using rollbacks with nested savepoints

For examples showing how to use `ROLLBACK` with nested savepoints, see [the `SAVEPOINT` documentation](savepoint.html).

### Rollback a transaction

Typically, an application conditionally executes rollbacks, but we can see their behavior by using `ROLLBACK` instead of `COMMIT` directly through SQL:
Expand Down Expand Up @@ -77,15 +87,16 @@ To use [advanced client-side transaction retries](advanced-client-side-transacti

{% include copy-clipboard.html %}
~~~ sql
> ROLLBACK TO SAVEPOINT cockroach_restart;
> ROLLBACK TO SAVEPOINT my_retry_savepoint;
~~~

For examples of retrying transactions in an application, check out the transaction code samples in our [Build an App with CockroachDB](build-an-app-with-cockroachdb.html) tutorials.

## See also

- [`SAVEPOINT`](savepoint.html)
- [Transactions](transactions.html)
- [`BEGIN`](begin-transaction.html)
- [`COMMIT`](commit-transaction.html)
- [`SAVEPOINT`](savepoint.html)
- [`RELEASE SAVEPOINT`](release-savepoint.html)
- [`SHOW SAVEPOINT STATUS`](show-savepoint-status.html)
Loading

0 comments on commit ba35ff3

Please sign in to comment.