As long you use a DB inside the transaction and lock the table (row) you will have such behaviour.
The application(s) are not very scalable.
You should decouple the key generation and use a different for each app.
Or you might cache a couple of keys in each application outside this transactions (i.e. use a new transaction to refill the internal cache)
Drawback is that you might loose some keys if the server goes down or crash.