Hello,
I believe that my program is suffering from some sort of deadlock, and I was hoping for some feedback.
I am helping to develop a trading system
using EJBs, Oracle 9i, and Bea Weblogic 7.0. The system provides an entity
EJB called LiveOrder that exposes several finder methods, most of which return java.util.Collections of LiveOrder EJBs.
In weblogic-ejb-jar.xml, I have set the transaction isolation-levels for these finders to TRANSACTION_READ_COMMITTED_FOR_UPDATE (b/c TRANSACTION_SERIALIZABLE isn't really supported by Oracle), in an effort to eliminate phantom reads, which occur frequently if I do not use this isolation level. These finders all use transaction attribute 'Required'.
It is my understanding that any transaction that calls any of these finders either will lock the database if no other transaction already owns the lock, or will wait until the lock is released if another transaction owns that lock. It also is my understanding that a transaction that owns a lock will always release any locks acquired upon expiration of that transaction (whether that be via commit or via rollback).
However, this doesn't always appear the case: I have noticed occassionally that several clients "hang," as they wait for the lock that, for some reason, is not being released by its transaction. There do not appear to be any exceptions thrown by the system prior to the system hanging, and the Weblogic administration tool states that all transactions have been committed.
If it helps, I have included the general algorithm for the main (i.e., most expensive) transaction:
1. a client calls a stateless session EJB's processOrder method (which should implicitly start a new transaction, b/c this method has attibute 'RequiresNew')
2. the transaction invokes the LiveOrder finder method (this should lock the DB, so subsequent callers should block until the lock is released).
3. the transaction invokes another LiveOrder finder method, returning a separate set of data.
4. the transaction invokes a finder method from a separate entity EJB (called Security), which maps to a "read-only" table in the DB (default transaction-isolation level, Required attribute).
5. the transaction invokes a finder method from yet another separate entity EJB (called SecurityMarketValues), which maps to some other table (not read-only) in the DB (again, default transaction-isolation level, Required attribute).
6. the transaction writes to the SecurityMarketValues entity EJB.
7. the transaction writes to the LiveOrders retrieved from steps 2 and 3.
8. the transaction ends by exiting method processOrder (thus releasing the locks on the LiveOrder table in the DB).
In the system, there also exist other transactions that occassionally call the LiveOrder EJB finder methods, but only briefly to take a "snapshot" of the live order table (i.e., these transactions do not make calls to other DB tables, and close transactions almost immediately after starting them)
Like I mentioned before, the system sometimes works, and sometimes it hangs. Any ideas? I'm running out...
Thanks,
Jon