Skip to content
Open
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
48 changes: 48 additions & 0 deletions java/working-with-cql/query-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,54 @@ import static com.sap.cds.ql.cqn.CqnLock.Mode.SHARED;
Select.from("bookshop.Books").byId(1).lock(SHARED);
```

#### Wait Strategies

If the selected rows are already locked by another transaction, by default, the query waits until the lock is released. You can specify a [wait strategy](https://javadoc.io/doc/com.sap.cds/cds4j-api/latest/com/sap/cds/ql/cqn/CqnLock.Wait.Strategy.html) to control whether and how long the query execution shall wait.

- `DEFAULT` - wait until the lock is released:

By default, if the selected rows are locked by another transaction, the query waits for the lock to be relased. If the lock is not released within the database's predefined timeout a `CdsLockTimeoutException` is thrown:
```java
Select.from("bookshop.Books").byId(1).lock();
```
- `WAIT` - wait unless given timeout expires:
```java
import static com.sap.cds.ql.cqn.CqnLock.Mode.EXCLUSIVE;

// wait max 10s
Select.from("bookshop.Books").byId(1).lock(EXCLUSIVE, 10);
```

- `NOWAIT` — fail _immediately_ if the rows are already locked:

```java
import static com.sap.cds.ql.cqn.CqnLock.Mode.EXCLUSIVE;
import static com.sap.cds.ql.cqn.CqnLock.Wait.NOWAIT;

Select.from("bookshop.Books").byId(1).lock(EXCLUSIVE, NOWAIT);
```
If any target row is locked, a `CdsLockTimeoutException` is thrown without waiting.

- `SKIP LOCKED` — skip locked rows and return only unlocked rows:

```java
import static com.sap.cds.ql.cqn.CqnLock.Mode.EXCLUSIVE;
import static com.sap.cds.ql.cqn.CqnLock.Wait.SKIP_LOCKED;

Select.from("bookshop.Books")
.where(b -> b.get("stock").gt(0))
.lock(EXCLUSIVE, SKIP_LOCKED);
```

::: warning
Rows that are currently locked by other transactions are silently excluded from the result.
:::
::: tip
This is useful for queue-like processing where multiple workers consume available items concurrently without blocking each other.
:::

#### Restrictions

Not every entity exposed via a CDS entity can be locked with the `lock()` clause. To use the `lock()` clause, databases require that the target of such statements is represented by one of the following:
- a single table
- a simple view, so that the database can unambiguously identify which rows to lock
Expand Down