Here is what I want to do:
I need to make sure that two threads can't enter the same method with the same user at the same time (the user beeing identified with some uniqueId).
Problem is I am running multiple instances of JBoss so the two threads can possibly be in two different VMs. Hence the locking should occur at the database level.
The transaction is across multiple databases and they don't support two phase commit. So I can't just start a transaction and have that magically happen.
I have to explicitely go into one of the DBs and grab a lock named after the uniqueId of the user. Once the thread finished, the lock is released.
This successfully prevents two threads from running conccurently on the same user.
However, I don't want to end up in a position where one Jboss instance crashed, leaving the lock in the DB.
So I have to have some kind of timeout when I try to acquire the lock.
My problem is now the following:
- I don't want to set the timeout to a small value because the method I am protecting is potentially lengthy. A too small value for a timeout would render the locking mechanism useless
- I don't want to set the timeout to a high value because then it would affect the user experience for the cases where it was indeed a stale lock.
My answer to this problem in straight java is simple:
Fire the protected method in its own thread, and refresh the lock time in the main tread until the method finishes.
That way I can have a timeout of 10 seconds, refresh the lock every 8 seconds while the method is running and eventually release the lock when the method returns.
With this I get:
- Quick detection of stalled locks
- Indefinite locking if the method is still running.
I am trying to achive the same effect under JBoss, but since I can't fire threads like that, I am a little stuck.
I assume there has to be some way to do this using MDB, but I'm not sure how ...
Any help is appreciated.