Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read Committed 40001 errors; lock promotion #18522

Merged
merged 9 commits into from
May 14, 2024
2 changes: 1 addition & 1 deletion src/current/v24.1/read-committed.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ To use locking reads:

- If you need to read and later update a row within a transaction, use `SELECT ... FOR UPDATE` to acquire an exclusive lock on the row. This guarantees data integrity between the transaction's read and write operations.

- If you need to read the latest version of a row, but not update the row, use `SELECT ... FOR SHARE` to block all concurrent writes on the row without unnecessarily blocking concurrent reads.
- If you need to read the latest version of a row, but not update the row, use `SELECT ... FOR SHARE` to acquire a shared lock on the row. This blocks all concurrent writes on the row without unnecessarily blocking concurrent reads.
taroface marked this conversation as resolved.
Show resolved Hide resolved

{{site.data.alerts.callout_success}}
This allows an application to build cross-row consistency constraints by ensuring that rows that are read in a `READ COMMITTED` transaction will not change before the writes in the same transaction have been committed.
Expand Down
10 changes: 9 additions & 1 deletion src/current/v24.1/select-for-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ Under `READ COMMITTED` isolation, CockroachDB uses the `SELECT ... FOR SHARE` lo
Shared locks are not enabled by default for `SERIALIZABLE` transactions. To enable shared locks for `SERIALIZABLE` transactions, configure the [`enable_shared_locking_for_serializable` session setting]({% link {{ page.version.version }}/session-variables.md %}). To perform [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) checks under `SERIALIZABLE` isolation with shared locks, configure the [`enable_implicit_fk_locking_for_serializable` session setting]({% link {{ page.version.version }}/session-variables.md %}). This matches the default `READ COMMITTED` behavior.
{{site.data.alerts.end}}

#### Lock behavior under `SERIALIZABLE` isolation
### Lock promotion

A shared lock can be "promoted" to an exclusive lock.

If a transaction that holds a shared lock on a row subsqeuently issues an exclusive lock on the row, this will cause the transaction to reacquire the lock, effectively "promoting" the shared lock to an exclusive lock.

A shared lock cannot be promoted until all other shared locks on the row are released. If two concurrent transactions attempt to promote their shared locks on a row, this will cause *deadlock* between the transactions, causing one transaction to abort with a `40001` error ([`ABORT_REASON_ABORTED_RECORD_FOUND`]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#abort_reason_aborted_record_found) or [`ABORT_REASON_PUSHER_ABORTED`]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#abort_reason_pusher_aborted)) returned to the client. The remaining open transaction will then promote its lock.

### Lock behavior under `SERIALIZABLE` isolation

{% include {{page.version.version}}/known-limitations/select-for-update-limitations.md %}

Expand Down
Loading