I seem to recall this problem from many years ago about how everything works in the INGRES database. There was no sequence in those days, so it took a lot of effort to find the best scaling solution for this problem with the best INGRES ideas of that day. I was fortunate enough to work with them so that, although my mind is sorry for less than any of them, proxmity = residual affect, and I saved something. That was one of the things. Let me see if I can remember.
1) for each counter you need row in a work table. 2) each time you need a number a) lock the row b) update it c) get its new value (you use returning for this which I avoid like the plague) d) commit the update to release your lock on the row
The reason for the fix is ββto try to get some scalability. There will always be a limit, but you do not serialize receiving a number for any period of time.
In the oracle world, we would improve the situation using the function defined as AUTONOMOUS_TRANSACTION to get the next number. If you think about it, this decision requires the resolution of the spaces that you said in order. By starting a room update regardless of the main transaction, you get scalability, but you enter spaces.
You will have to accept the fact that scalability will drop dramatically in this scenario. This is due to at least two reasons:
1) the sequence update / select / commit does everything possible to reduce the time during which the KEY string is locked, but it is still non-zero. Under heavy load, you will serialize and ultimately be limited.
2) you commit every time you receive a key. The end is an expensive operation that requires a lot of memory and file management from the database. It will also limit you.
In the end, you probably look at three or more load drop orders for a simultaneous transaction because you are not using sequences. I base this on my experience of the past.
But if the client requires it, what can you do right?
Good luck. I have not tested the code for syntax errors, I leave it to you.
create or replace function get_next_key (key_name_p in varchar2) return number is pragma autonomous_transaction; kev_v number; begin update key_table set key = key + 1 where key_name = key_name_p; select key_name into key_name_v from key_name where key_name = key_name_p; commit; return (key_v); end; / show errors