thatmikewilliams wrote:
Unless you set your isolation level to read-uncommited, having a flag won't help.
How about using a single thread to read the messages that need processing then handing them off to your pool of worked threads that do the actual updating. The dispatcher thread could keep track of the last message it read and use this to select the new messages.
Unfortunately having a single thread is not possible. I have multiple instances of this application and each instance is very high traffic, the various threads must be able to concurrently process the messages.
The flag solution is more of a manual process:
- read row from table and set 'locked by' and 'locked time' columns
- do some work
- either update row and null out the 'locked by' and 'locked time' columns so the row can be processed again or delete the row (depending on result of work above)
Using a 'locked time' I can put something in the query that ignores locks that have 'expired' which will be defined as having been locked for over x minutes. This is to prevent application crashes locking a row permanently.
I think this will work but ideally I would like the database to handle this. I would just like to use hibernate and tell oracle 'this row is locked so ignore it for other requests'. But I'm beginning to think this is not possible. It seems you can only get other requests to wait indefinitely or error since they will not ignore the locked row in their queries.