question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for `NOWAIT` / `SKIP LOCKED` options in locking clause

See original GitHub issue

Issue type:

[x] feature request

Database system/driver:

[x] mssql [x] mysql / mariadb [x] oracle [x] postgres

TypeORM version:

[x] latest


PostgreSQL, MySQL, MSSQL and Oracle (I think), and perhaps others, support NOWAIT and SKIP LOCKED options for row locking. The PostgreSQL documentation has a good explanation of these options, but in summary:

nowait

With the NOWAIT option, the statement reports an error if it is unable to take the lock.

SELECT * FROM jobs WHERE id = 5 FOR UPDATE NOWAIT

skip locked

With the SKIP LOCKED option, any selected rows that cannot be immediately locked are skipped.

SELECT * FROM jobs WHERE id = 5 FOR UPDATE SKIP LOCKED

Currently, TypeORM only supports the bare FOR UPDATE clause, via the pessimistic_write lock mode.

Some additional considerations:

  • These options are, in some databases, relatively new. SKIP LOCKED appeared in PostgreSQL 9.5 (2016). I think support in MySQL is even more recent. I’m not sure what TypeORM’s philosophy is on supporting newer SQL features?
  • NOWAIT, by design, returns an error if the row is locked, so it seems necessary that an implementation of this option would have to handle this gracefully (a new Error type?)

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

6reactions
pleerockcommented, Apr 30, 2018

To not confuse things I would go this way:

  1. deprecate setLock
  2. create lockMode() method that will do same as setLock right now, e.g. rename setLock method
  3. create lock() method that accepts string and do what you proposed

What do you think?

3reactions
clarkdavecommented, Apr 27, 2018

@pleerock These lock options aren’t specific to FOR UPDATE - they can be used with any “lock strength”, and also combined with an OF table_name to limit the lock to a specific table when multiple are involved.

For example, all of the following queries are valid:

SELECT * FROM table WHERE id = 1 FOR UPDATE;
SELECT * FROM table WHERE id = 1 FOR SHARE SKIP LOCKED;
SELECT * FROM table WHERE id = 1 FOR UPDATE NOWAIT;
SELECT * FROM table WHERE id = 1 FOR KEY SHARE SKIP LOCKED;

SELECT a.*, b.*
  FROM a
  LEFT JOIN b ON b.id = a.b_id
  FOR UPDATE OF a
  SKIP LOCKED;

With that in mind, could TypeORM support a more generic way to set the locking clause for a query? As an example from the wild, ActiveRecord lets you pass through an arbitrary string:

User
  .lock('FOR UPDATE OF users SKIP LOCKED')
  .where(:id => 1)
  .first

Maybe this could be supported in TypeORM by adding another override to setLock which accepts a raw string to use as the locking clause, as with other methods like addGroupBy:

const user = await connection
  .getRepository(User)
  .createQueryBuilder('user')
  .leftJoinAndSelect('user.photos', 'photo')
  .where({ id: 1 })
  .setLock('FOR UPDATE OF user SKIP LOCKED')
  // .setLock('FOR KEY SHARE OF user')
  // .setLock('FOR NO KEY UPDATE NOWAIT')
  // .setLock('FOR SHARE OF user')
  .getOne()

Thoughts?

Read more comments on GitHub >

github_iconTop Results From Across the Web

15.7.2.4 Locking Reads
A locking read that uses NOWAIT never waits to acquire a row lock. The query executes immediately, failing with an error if a...
Read more >
MySQL 8.0.1: Using SKIP LOCKED and NOWAIT to handle ...
Lock only the tables you want. ... FOR UPDATE OF s SKIP LOCKED;. Aliases in the locking clause work just like aliases in...
Read more >
What is SKIP LOCKED for in PostgreSQL 9.5? - EDB
Tries to acquire a lock on each row. If it fails to acquire the lock, it ignores the row as if it wasn't...
Read more >
MySQL 8.0 Hot Rows with NOWAIT and SKIP LOCKED
MySQL 8.0 offers developers two new features to support application locking strategies NOWAIT and SKIP LOCKED. Percona MySQL DBA Arunjith ...
Read more >
MySQL vs. MariaDB: WAIT, NOWAIT, SKIP LOCKED
NOWAIT · MariaDB supports this syntax for some DDL statements ( ALTER TABLE and its shortcuts), LOCK TABLES , and SELECT . ·...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found