I have some services, which can execute insert
to insert new elements into a table of my database (Postgresql). So in the view of the database, many insert
s are executed concurrently.
My question is if it's possible to keep the insertion order with some column of the table.
For example, there are three insert
s:
INSERT INTO Users (UserName, Id) VALUES ('Tom', 1);
INSERT INTO Users (UserName, Id) VALUES ('Jerry', 2);
INSERT INTO Users (UserName, Id) VALUES ('Joey', 3);
They are executing concurrently.
For some reason, the second insert
is delayed. In this case, when the third insert
is now executing, I'm expecting one of the two results as below:
- the
insert
fails; - the
insert
succeed with a new Id2
.
Is there some mechanism to achieve this?
Why do I need this
There is a ID generator which generate IDs with snowflake algorithm. Concurrent insert
s are executed in multi-threads. when reading data from the table, I want to make range queries like this:
select * from my_table where Id > a limit 5
select * from my_table where Id > b limit 5
select * from my_table where Id > c limit 5
...
a
, b
and c
are the last Id coming from the previous select
.
| --- a --- | --- b --- | --- c --- |
The problem is when the second select
is executing, it still might be possible to make a insert
in the a
zone because of concurrent insert
. If this happen, I will have no chance to read the delayed inserted data.
Serializable
isolation level but you will lose yourconcurrency
. But I wondering why would you need such a mechanism when you can simply order by using ID once they are inserted in any order?ORDER BY
clause. Secondly, when you use theLIMIT
clause against your table without anORDER BY
then you're receiving the rows almost randomly because it's non-deterministic. Think of the table like a box of different colored balls, andLIMIT
is like you stuck your hand in the box and pulled out 5 balls. You can get any colored balls that way since they're unordered.sequence
in database as a primary key instead of your snowflake ID there is still chance they are inserted out of order.where Id <= a
wherea
is your lastId
for thea
group, etc.