'Is this INSERT statement containing SELECT subquery safe for multiple concurrent writes?

In Postgres, suppose I have the following table to be used like to a singly linked list, where each row has a reference to the previous row.

                       Table node
   Column    |           Type           | Collation | Nullable |       Default
-------------+--------------------------+-----------+----------+----------------------
 id          | uuid                     |           | not null | gen_random_uuid()
 created_at  | timestamp with time zone |           | not null | now()
 name        | text                     |           | not null |
 prev_id     | uuid                     |           |          |

I have the following INSERT statement, which includes A SELECT to look up the last row as data for the new row to be inserted.

INSERT INTO node(name, prev_id)
VALUES (
  :name,
  (
    SELECT id
    FROM node
    ORDER BY created_at DESC
    LIMIT 1
  )
)
RETURNING id;

I understand storing prev_id may seem redundant in this example (ordering can be derived from created_at), but that is beside the point. My question: Is the above INSERT statement safe for multiple concurrent writes? Or, is it necessary to explicitly use LOCK in some way?

For clarity, by "safe", I mean is it possible that by the time the SELECT subquery executed and found the "last row", another concurrent query would have just finished an insert, so the "last row" found earlier is no longer the last row, so this insert would use the wrong "last row" value. The effect is multiple rows may share the same prev_id values, which is invalid for a linked list structure.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source