Concurrent transactions result in race condition with unique constraint on insert
Try the insert first, with on conflict ... do nothing and returning id.
If the value already exists, you will get no result from this statement, so you have then to execute a select to get the ID.

If two transactions try to do this at the same time, one of them will block on the insert (because the database does not yet know if the other transaction will commit or rollback), and continue only after the other transaction has finished.