The conflict might happen, indeed, but that is okay.
With transactional databases a data modification query might fail because of conflicts. The database will detect a conflicts and report it. (For example with a "could not serialize access due to concurrent update
" error message). It is a common practice to check the status of the transaction and repeat it if a conflict happened.
Similarly, when you insert a new queue number into the database you must check if the transactional is sucessful and repeat it if it isn't.
You can create an autoincrement as Ali suggested but I often prefer the simpler "max + 1" logic.
Notice, however, that the autoincrement and the "max + 1" behave differently: if you delete a number of entries at the end of the queue (or if some insert transactions rollback), the "max + 1" approach will reuse their numbers. The autoincrement will leave these numbers unused.
P.S. An example: http://sqlfiddle.com/#!15/06b87/7
CREATE TABLE queue (id INTEGER NOT NULL PRIMARY KEY);
INSERT INTO queue SELECT COALESCE (MAX (id) + 1, 1) FROM queue RETURNING id;
(See also postgreSQL function for last inserted ID).