From 5945ee85a29631b62665cefd091ef77dde687ca3 Mon Sep 17 00:00:00 2001 From: Ryan Kuo Date: Fri, 20 Sep 2024 15:52:20 -0400 Subject: [PATCH 1/2] mixing transaction isolation levels --- src/current/_includes/v23.2/sql/isolation-levels.md | 4 +++- src/current/_includes/v23.2/sql/mixed-isolation-levels.md | 8 ++++++++ src/current/_includes/v24.1/sql/isolation-levels.md | 4 +++- src/current/_includes/v24.1/sql/mixed-isolation-levels.md | 8 ++++++++ src/current/_includes/v24.2/sql/isolation-levels.md | 4 +++- src/current/_includes/v24.2/sql/mixed-isolation-levels.md | 8 ++++++++ 6 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 src/current/_includes/v23.2/sql/mixed-isolation-levels.md create mode 100644 src/current/_includes/v24.1/sql/mixed-isolation-levels.md create mode 100644 src/current/_includes/v24.2/sql/mixed-isolation-levels.md diff --git a/src/current/_includes/v23.2/sql/isolation-levels.md b/src/current/_includes/v23.2/sql/isolation-levels.md index f711975a3b7..ef1ec385336 100644 --- a/src/current/_includes/v23.2/sql/isolation-levels.md +++ b/src/current/_includes/v23.2/sql/isolation-levels.md @@ -2,4 +2,6 @@ Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACI 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 [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}). For a demonstration of how `SERIALIZABLE` prevents write skew anomalies, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). -{% include_cached new-in.html version="v23.2" %} CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and [retries]({% link {{ page.version.version }}/developer-basics.md %}#transaction-retries). Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). \ No newline at end of file +{% include_cached new-in.html version="v23.2" %} CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and [retries]({% link {{ page.version.version }}/developer-basics.md %}#transaction-retries). Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). + +{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} \ No newline at end of file diff --git a/src/current/_includes/v23.2/sql/mixed-isolation-levels.md b/src/current/_includes/v23.2/sql/mixed-isolation-levels.md new file mode 100644 index 00000000000..505a5b0e13a --- /dev/null +++ b/src/current/_includes/v23.2/sql/mixed-isolation-levels.md @@ -0,0 +1,8 @@ +{% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} + +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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: + +- 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. \ No newline at end of file diff --git a/src/current/_includes/v24.1/sql/isolation-levels.md b/src/current/_includes/v24.1/sql/isolation-levels.md index f6203ad37c2..29afd53f2b0 100644 --- a/src/current/_includes/v24.1/sql/isolation-levels.md +++ b/src/current/_includes/v24.1/sql/isolation-levels.md @@ -2,4 +2,6 @@ Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACI 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 [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). -CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `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, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). \ No newline at end of file +CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `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, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). + +{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} \ No newline at end of file diff --git a/src/current/_includes/v24.1/sql/mixed-isolation-levels.md b/src/current/_includes/v24.1/sql/mixed-isolation-levels.md new file mode 100644 index 00000000000..505a5b0e13a --- /dev/null +++ b/src/current/_includes/v24.1/sql/mixed-isolation-levels.md @@ -0,0 +1,8 @@ +{% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} + +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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: + +- 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. \ No newline at end of file diff --git a/src/current/_includes/v24.2/sql/isolation-levels.md b/src/current/_includes/v24.2/sql/isolation-levels.md index f6203ad37c2..29afd53f2b0 100644 --- a/src/current/_includes/v24.2/sql/isolation-levels.md +++ b/src/current/_includes/v24.2/sql/isolation-levels.md @@ -2,4 +2,6 @@ Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACI 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 [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). -CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `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, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). \ No newline at end of file +CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `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, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). + +{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} \ No newline at end of file diff --git a/src/current/_includes/v24.2/sql/mixed-isolation-levels.md b/src/current/_includes/v24.2/sql/mixed-isolation-levels.md new file mode 100644 index 00000000000..505a5b0e13a --- /dev/null +++ b/src/current/_includes/v24.2/sql/mixed-isolation-levels.md @@ -0,0 +1,8 @@ +{% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} + +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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: + +- 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. \ No newline at end of file From f341970510ba3e424092bf5f7543e00adbab577a Mon Sep 17 00:00:00 2001 From: Ryan Kuo Date: Mon, 23 Sep 2024 16:35:35 -0400 Subject: [PATCH 2/2] address michae2 comment --- src/current/_includes/v23.2/sql/mixed-isolation-levels.md | 8 ++++++-- src/current/_includes/v24.1/sql/mixed-isolation-levels.md | 8 ++++++-- src/current/_includes/v24.2/sql/mixed-isolation-levels.md | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/current/_includes/v23.2/sql/mixed-isolation-levels.md b/src/current/_includes/v23.2/sql/mixed-isolation-levels.md index 505a5b0e13a..440e29f24bd 100644 --- a/src/current/_includes/v23.2/sql/mixed-isolation-levels.md +++ b/src/current/_includes/v23.2/sql/mixed-isolation-levels.md @@ -1,8 +1,12 @@ {% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} -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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: +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. \ No newline at end of file +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. \ No newline at end of file diff --git a/src/current/_includes/v24.1/sql/mixed-isolation-levels.md b/src/current/_includes/v24.1/sql/mixed-isolation-levels.md index 505a5b0e13a..440e29f24bd 100644 --- a/src/current/_includes/v24.1/sql/mixed-isolation-levels.md +++ b/src/current/_includes/v24.1/sql/mixed-isolation-levels.md @@ -1,8 +1,12 @@ {% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} -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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: +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. \ No newline at end of file +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. \ No newline at end of file diff --git a/src/current/_includes/v24.2/sql/mixed-isolation-levels.md b/src/current/_includes/v24.2/sql/mixed-isolation-levels.md index 505a5b0e13a..440e29f24bd 100644 --- a/src/current/_includes/v24.2/sql/mixed-isolation-levels.md +++ b/src/current/_includes/v24.2/sql/mixed-isolation-levels.md @@ -1,8 +1,12 @@ {% if page.name == "transactions.md" %}### Mixed isolation levels{% else if page.name == "transaction-layer.md" %}#### Mixed isolation levels{% endif %} -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, given a `SERIALIZABLE` transaction `S` and a `READ COMMITTED` transaction `R`: +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. \ No newline at end of file +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. \ No newline at end of file