Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Atomic UPDATE to increment integer in Postgresql

I'm trying to figure out if the query below is safe to use for the following scenario:

I need to generate sequential numbers, without gaps. As I need to track many of them, I have a table holding sequence records, with a sequence integer column.

To get the next sequence, I'm firing off the SQL statement below.

WITH updated AS (
  UPDATE sequences SET sequence = sequence + ? 
  WHERE sequence_id = ? RETURNING sequence
)
SELECT * FROM updated;

My question is: is the query below safe when multiple users fire this query at the database at the same time without explicitly starting a transaction?

Note: the first parameter is usually 1, but could also be 10 for example, to get a block of 10 new sequence numbers

like image 270
Paul Avatar asked Oct 20 '16 19:10

Paul


People also ask

Are Postgres updates Atomic?

PostgreSQL: Update is not atomic.

Is PostgreSQL Atomic?

A PostgreSQL transaction is atomic, consistent, isolated, and durable. These properties are often referred to as ACID: Atomicity guarantees that the transaction completes in an all-or-nothing manner. Consistency ensures the change to data written to the database must be valid and follow predefined rules.

What is Upsert in PostgreSQL?

The UPSERT statement is a DBMS feature that allows a DML statement's author to either insert a row or if the row already exists, UPDATE that existing row instead. That is why the action is known as UPSERT (simply a mix of Update and Insert).


1 Answers

Yes, that is safe.

While one such statement is running, all other such statements are blocked on a lock. The lock will be released when the transaction completes, so keep your transactions short. On the other hand, you need to keep your transaction open until all your work is done, otherwise you might end up with gaps in your sequence.
That is why it is usually considered a bad idea to ask for gapless sequences.

like image 95
Laurenz Albe Avatar answered Sep 18 '22 17:09

Laurenz Albe