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

[doc] Pessimistic locking FAQ #24969

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Concurrency control
headerTitle: Concurrency control
linkTitle: Concurrency control
description: Details about Concurrency control in YSQL
description: Details about Concurrency control and optimistic and pessimistic locking in YSQL
menu:
preview:
identifier: architecture-concurrency-control
Expand All @@ -13,7 +13,7 @@ type: docs

[Concurrency control](https://en.wikipedia.org/wiki/Concurrency_control) in databases ensures that multiple transactions can execute concurrently while preserving data integrity. Concurrency control is essential for correctness in environments where two or more transactions can access the same data at the same time.

YugabyteDB provides two policies to handle conflicts between concurrent transactions as described in the following sections.
YugabyteDB supports both "optimistic locking" and "pessimistic locking", however YugabyteDB uses the more precise terminology _Fail-on-conflict_ and _Wait-on-conflict_ to describe its concurrency control mechanisms.

For information on how row-level explicit locking clauses behave with these concurrency control policies, refer to [Row-level explicit locking clauses](#row-level-explicit-locking-clauses).

Expand Down Expand Up @@ -308,7 +308,7 @@ Note that the retries will not be performed in case the amount of data to be sen

## Wait-on-Conflict

This mode of concurrency control is applicable only for YSQL and provides the same semantics as PostgreSQL.
This mode of concurrency control (sometimes referred to as "pessimistic locking") is applicable only for YSQL and provides the same semantics as PostgreSQL.

In this mode, transactions are not assigned priorities. If a conflict occurs when a transaction T1 tries to read, write, or lock a row in a conflicting mode with a few other concurrent transactions, T1 will **wait** until all conflicting transactions finish by either committing or rolling back. Once all conflicting transactions have finished, T1 will:

Expand Down
20 changes: 17 additions & 3 deletions docs/content/preview/faq/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ The [YSQL](../../api/ysql/) API is compatible with PostgreSQL. This means Postgr

- YugabyteDB's API compatibility is not aimed at lift-and-shift porting of existing applications written for the original language. This is because existing applications are not written to take advantage of the distributed, strongly-consistent storage architecture that YugabyteDB provides. For such existing applications, you should modify your previously monolithic PostgreSQL and/or non-transactional Cassandra data access logic as you migrate to YugabyteDB.

### Can I insert data using YCQL, but read using YSQL, or vice versa?

The YugabyteDB APIs are currently isolated and independent from one another. Data inserted or managed by one API cannot be queried by the other API. Additionally, Yugabyte does not provide a way to access the data across the APIs. An external framework, such as Presto, might be helpful for basic use cases. For an example that joins YCQL and YSQL data, see the blog post about [Presto on YugabyteDB: Interactive OLAP SQL Queries Made Easy](https://www.yugabyte.com/blog/presto-on-yugabyte-db-interactive-olap-sql-queries-made-easy-facebook/).

Allowing YCQL tables to be accessed from the PostgreSQL-compatible YSQL API as foreign tables using foreign data wrappers (FDW) is on the roadmap. You can comment or increase the priority of the associated [GitHub](https://github.com/yugabyte/yugabyte-db/issues/830) issue.

## YSQL compatibility with PostgreSQL

### What is the extent of compatibility with PostgreSQL?
Expand All @@ -110,11 +116,19 @@ Explore SQL features

YugabyteDB's goal is to remain as compatible with PostgreSQL as much as possible. If you see a feature currently missing, you can file a [GitHub issue](https://github.com/yugabyte/yugabyte-db/issues).

### Can I insert data using YCQL, but read using YSQL, or vice versa?
### Does YugabyteDB support optimistic/pessimistic locking?

The YugabyteDB APIs are currently isolated and independent from one another. Data inserted or managed by one API cannot be queried by the other API. Additionally, Yugabyte does not provide a way to access the data across the APIs. An external framework, such as Presto, might be helpful for basic use cases. For an example that joins YCQL and YSQL data, see the blog post about [Presto on YugabyteDB: Interactive OLAP SQL Queries Made Easy](https://www.yugabyte.com/blog/presto-on-yugabyte-db-interactive-olap-sql-queries-made-easy-facebook/).
YugabyteDB effectively supports both optimistic and pessimistic locking.

Allowing YCQL tables to be accessed from the PostgreSQL-compatible YSQL API as foreign tables using foreign data wrappers (FDW) is on the roadmap. You can comment or increase the priority of the associated [GitHub](https://github.com/yugabyte/yugabyte-db/issues/830) issue.
However YugabyteDB has moved away from using the terms "optimistic locking" and "pessimistic locking" in favor of more precise terminology to describe its concurrency control mechanisms. YugabyteDB uses the concepts of "Fail-on-conflict" and "Wait-on-conflict" to describe how it handles conflicts between concurrent transactions:

- Fail-on-conflict: This is similar to what was previously referred to as "optimistic locking". In this mode, when a conflict is detected, the transaction aborts other conflicting transactions or fails itself and may need to be retried.

- Wait-on-conflict: This is similar to what was previously called "pessimistic locking". In this mode, when a conflict is detected, the transaction waits for the conflicting transaction to complete before proceeding. This is the same behavior as PostgreSQL.

{{<lead link="../../architecture/transactions/concurrency-control/">}}
To learn more, refer to [Concurrency control](../../architecture/transactions/concurrency-control/).
{{</lead>}}

## YCQL compatibility with Apache Cassandra QL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Concurrency control
headerTitle: Concurrency control
linkTitle: Concurrency control
description: Details about Concurrency control in YSQL
description: Details about Concurrency control and optimistic and pessimistic locking in YSQL
menu:
v2024.2:
identifier: architecture-concurrency-control
Expand All @@ -13,7 +13,7 @@ type: docs

[Concurrency control](https://en.wikipedia.org/wiki/Concurrency_control) in databases ensures that multiple transactions can execute concurrently while preserving data integrity. Concurrency control is essential for correctness in environments where two or more transactions can access the same data at the same time.

YugabyteDB provides two policies to handle conflicts between concurrent transactions as described in the following sections.
YugabyteDB supports both "optimistic locking" and "pessimistic locking", however YugabyteDB uses the more precise terminology _Fail-on-conflict_ and _Wait-on-conflict_ to describe its concurrency control mechanisms.

For information on how row-level explicit locking clauses behave with these concurrency control policies, refer to [Row-level explicit locking clauses](#row-level-explicit-locking-clauses).

Expand Down Expand Up @@ -308,7 +308,7 @@ Note that the retries will not be performed in case the amount of data to be sen

## Wait-on-Conflict

This mode of concurrency control is applicable only for YSQL and provides the same semantics as PostgreSQL.
This mode of concurrency control (sometimes referred to as "pessimistic locking") is applicable only for YSQL and provides the same semantics as PostgreSQL.

In this mode, transactions are not assigned priorities. If a conflict occurs when a transaction T1 tries to read, write, or lock a row in a conflicting mode with a few other concurrent transactions, T1 will **wait** until all conflicting transactions finish by either committing or rolling back. Once all conflicting transactions have finished, T1 will:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ BEGIN;
COMMIT;
```

The `BEGIN` and `COMMIT` block is needed when you have multiple statements to be executed as part of a transaction. YugabyteDB treats every ad-hoc individual SQL statement as being executed in a transaction.
The BEGIN and COMMIT block is needed when you have multiple statements to be executed as part of a transaction. YugabyteDB treats every ad-hoc individual SQL statement as being executed in a transaction.

If you decide to cancel the transaction and not commit it, you can issue a `ROLLBACK` instead of a `COMMIT`. You can also control the rollback of a subset of statements using `SAVEPOINT`. After rolling back to a savepoint, it continues to be defined, so you can roll back to it several times.
If you decide to cancel the transaction and not commit it, you can issue a ROLLBACK instead of a COMMIT. You can also control the rollback of a subset of statements using SAVEPOINT. After rolling back to a savepoint, it continues to be defined, so you can roll back to it several times.

As all transactions in YugabyteDB are guaranteed to be [ACID](../../../../architecture/transactions/transactions-overview/) compliant, errors can be thrown during transaction processing to ensure correctness guarantees are not violated. YugabyteDB returns different [error codes](../transactions-errorcodes-ysql/) for each case with details. Applications need to be designed to do [retries](../transactions-retries-ysql/) correctly for high availability.

Expand Down Expand Up @@ -87,12 +87,13 @@ SELECT * FROM txndemo WHERE k=1 FOR UPDATE;
```

YugabyteDB supports the following types of explicit row locks:

| Lock | Description |
| :--- | :---------- |
| **FOR UPDATE** | Strongest and exclusive lock. Prevents all other locks on these rows till the transaction ends.|
| **FOR&nbsp;NO&nbsp;KEY&nbsp;UPDATE** | Weaker than `FOR UPDATE` and exclusive. Will not block `FOR KEY SHARE` commands.|
| **FOR SHARE** | Shared lock that does not block other `FOR SHARE` and `FOR KEY SHARE` commands.|
| **FOR KEY SHARE** | Shared lock that does not block other `FOR SHARE`, `FOR KEY SHARE`, and `FOR NO KEY UPDATE` commands.|
| **FOR&nbsp;NO&nbsp;KEY&nbsp;UPDATE** | Weaker than FOR UPDATE and exclusive. Will not block FOR KEY SHARE commands.|
| **FOR SHARE** | Shared lock that does not block other FOR SHARE and FOR KEY SHARE commands.|
| **FOR KEY SHARE** | Shared lock that does not block other FOR SHARE, FOR KEY SHARE, and FOR NO KEY UPDATE commands.|

{{<tip title="Examples">}}
For more details and examples related to these locking policies, see [Explicit locking](../../../../explore/transactions/explicit-locking/).
Expand Down Expand Up @@ -141,7 +142,7 @@ All applications need to be tuned to get the best performance. YugabyteDB suppor

- Convert a multi-statement transaction affecting a single row into a [fast-path](../transactions-performance-ysql/#fast-single-row-transactions) transaction.
- [Avoid long waits](../transactions-performance-ysql/#avoid-long-waits) with the right timeouts.
- [Minimize conflict errors](../transactions-performance-ysql/#minimize-conflict-errors) with `ON CONFLICT` clause.
- [Minimize conflict errors](../transactions-performance-ysql/#minimize-conflict-errors) with ON CONFLICT clause.
- [Uninterrupted long scans](../transactions-performance-ysql/#large-scans-and-batch-jobs)
- [Minimize round trips](../transactions-performance-ysql/#stored-procedures-minimize-round-trips) with stored procedures.

Expand Down Expand Up @@ -198,7 +199,7 @@ SET default_transaction_deferrable = TRUE;
```

{{<note title="Note">}}
The `DEFERRABLE` transaction property has no effect unless the transaction is also `SERIALIZABLE` and `READ ONLY`.
The DEFERRABLE transaction property has no effect unless the transaction is also SERIALIZABLE and READ ONLY.
{{</note>}}

##### idle_in_transaction_session_timeout
Expand Down
16 changes: 8 additions & 8 deletions docs/content/v2024.2/explore/transactions/explicit-locking.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ YugabyteDB's YSQL supports explicit row-level locking, similar to PostgreSQL. Ex

The following types of row locks are supported:

* `FOR UPDATE`
* `FOR NO KEY UPDATE`
* `FOR SHARE`
* `FOR KEY SHARE`
* FOR UPDATE
* FOR NO KEY UPDATE
* FOR SHARE
* FOR KEY SHARE

The following example uses the `FOR UPDATE` row lock with the [fail-on-conflict](../../../architecture/transactions/concurrency-control/#fail-on-conflict) concurrency control policy. First, a row is selected for update, thereby locking it, and subsequently updated. A concurrent transaction should not be able to abort this transaction by updating the value of that row after the row is locked.
The following example uses the FOR UPDATE row lock with the [fail-on-conflict](../../../architecture/transactions/concurrency-control/#fail-on-conflict) concurrency control policy. First, a row is selected for update, thereby locking it, and subsequently updated. A concurrent transaction should not be able to abort this transaction by updating the value of that row after the row is locked.

{{% explore-setup-single %}}

Expand All @@ -43,9 +43,9 @@ yugabyte=# CREATE TABLE t (k VARCHAR, v VARCHAR);
yugabyte=# INSERT INTO t VALUES ('k1', 'v1');
```

Next, connect to the universe using two independent `ysqlsh` instances. You can connect both session `ysqlsh` instances to the same server or to different servers.
Next, connect to the universe using two independent ysqlsh instances. You can connect both session ysqlsh instances to the same server or to different servers.

Begin a transaction in the first session and perform a `SELECT FOR UPDATE` on the row in the table `t`. This locks the row for an update as a part of a transaction that has a very high priority (that is, in the `high priority bucket`, as explained in [Transaction priorities](../../../architecture/transactions/transaction-priorities/)):
Begin a transaction in the first session and perform a SELECT FOR UPDATE on the row in the table `t`. This locks the row for an update as a part of a transaction that has a very high priority (that is, in the `high priority bucket`, as explained in [Transaction priorities](../../../architecture/transactions/transaction-priorities/)):

```sql
yugabyte=# BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Expand Down Expand Up @@ -76,7 +76,7 @@ yugabyte=# UPDATE t SET v='v1.1' WHERE k='k1';
ERROR: All transparent retries exhausted. Operation failed. Try again: bb3aace4-5de2-41f9-981e-d9ca06671419 Conflicts with higher priority transaction: d4dadbf8-ca81-4bbd-b68c-067023f8ee6b
```

This operation fails because it conflicts with the row-level lock and as per `Fail-on-Conflict` concurrency control policy, the transaction aborts itself because it has a lower priority.
This operation fails because it conflicts with the row-level lock and as per Fail-on-Conflict concurrency control policy, the transaction aborts itself because it has a lower priority.

Note that the error message appears after all [best-effort statement retries](../../../architecture/transactions/concurrency-control/#best-effort-internal-retries-for-first-statement-in-a-transaction) have been exhausted.

Expand Down