In a table with three columns (serial id, varchar name, varchar email)
and having two different transactions executing concurrently as the ones bellow:
Transaction 1:
BEGIN;
INSERT INTO public.users (name, email) VALUES ('tart', 'tart@warm.com');
INSERT INTO public.users (name, email) VALUES ('tart123', 'tart123@warm123.com');
COMMIT;
Transaction2:
BEGIN;
INSERT INTO public.users (name, email) VALUES ('raspy', 'raspy@sun.com');
INSERT INTO public.users (name, email) VALUES ('raspy123', 'raspy123@sun123.com');
COMMIT;
Is it possible that the outcome becomes the following?
1 | tart | tart@warm.com
2 | raspy | raspy@sun.com
3 | tart123 | tart123@warm123.com
4 | raspy123 | raspy123@sun123.com
Best Answer
serial
is defined as such in PostgreSQL documentation:They also provide this warning:
And if you go over to
nextval
documentation you get:The sequence is a shared object, among all your content. Each call to
INSERT
will by default call the underlying sequencenextval
and will provide one value, irrespective to what happened in the transaction just before. So the value will just depend exactly on the order of operations, and not which transaction started first or things like that.You could as well get this result (depending on what else is happening elsewhere in your DB at the same time):
Or
(which is probably what you expected, but has no specific guarantee to happen).
A sequence just guarantees you to "never" get the same value in two separate places, it does not guarantee lack of holes or monotony in increments, especially accross multiple transactions.