I am using JBoss TreeCache in a non-JBoss application server. JBoss is creating threads which use the JTA transaction manager. I guess the main use would be the eviction thread.
Apparently this is prohibited by the J2EE spec and frowned upon by the servlet specification. I have included some text from the IBM documentation below. Is this taken into consideration by TreeCache? Perhaps the integration with the application servers thread pool works OK with JBoss application server, but what about other J2EE containers? My understanding was the TreeCache could be used in any container?
The issue is I am having is it appears that some JTA transactions are hanging when I stop the application server. I am assuming the transactions are hanging because they are being managed by a thread which the application container does not know about, so the shutdown is not clean. Can someone enlighten me if I am wrong?
The EJB 2.0 and 2.1 specifications prohibit an EJB from managing threads. This includes starting, stopping, suspending and resuming threads.
EJB 2.0, Section 24.1.2 and EJB 2.1, Section 25.1.2 state the following:
The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread; or to change a thread?s priority or name. The enterprise bean must not attempt to manage thread groups.
For a servlet, the J2EE 1.3 and 1.4 specifications allow web components to create and manage threads, however, the execution and behavior of these threads must be tightly monitored by the application, not the application server. The specifications state the following:
J2EE 1.3 and J2EE 1.4:
J2EE.126.96.36.199 Transaction Requirements
If a web component creates a thread, the J2EE platform must ensure that the newly created thread is not associated with any JTA transaction.
J2EE.4.2.3 Transactions and Threads
JTA transactions should be started and completed in the thread in which the service method is called. Additional threads that are created for any purpose should not attempt to start JTA transactions.
For a little more background, here are the log statements I get after the JTA transaction hangs.
WARN [Thread-31] (?:?) 2006-05-10 09:14:36,340 - evictCacheNode(): evictCacheNode time out. Will try later.
ERROR [Thread-31] (?:?) 2006-05-10 09:14:51,340 - write lock for /fleetcycle/domain/labor/LaborCode/fleetcycle.domain.labor.LaborCode#laborcode38 could not be acquired after 15000 ms. Locks: Read lock owners: [:352]
Write lock owner: null
(caller=Thread[Thread-31,5,main], lock info: read owners=[:352] (activeReaders=1, activeWriter=null, waitingReaders=0, waitingWriters=0, waitingUpgrader=0))
As far as thread creation is concerned i dont think JBossCache is creating Threads. The reason why you are seeing the log messages that you posted below is because i believe you are using PESSIMISTIC NodeLockingScheme. More about PESSIMISTIC locking approach can be found here:
And for eviction related stuff JBossCache uses a TimerTask, as far as i know.
If TimerTask is being used, then a new thread is created everytime the timer task executes, right? And since that task needs access to the JTA transaction manager to establish a write lock for eviction
So, this would mean there is a new thread, not created by the servlet/ejb container, which is associated with the container-managed transaction. Am I correct on this?
Thanks for the tip on optimistic locking. I am going to look at this for the future, but it is a little scary if the transactions are going to fail if an out-of-sync version is detected. Hopefully these cases would be few and far between but even a couple would not be ideal.
JBossCache does use a single thread for eviction timer (only if eviction is configured). However, it does not access the JTA transaction though. So I don't think your problem is caused by that. And I dont think this is relevant to JEE discussion.
Please forgive my ignorance, but I would like to understand what is happening when the TreeCache LRU eviction thread runs in a REPL_SYNC mode.
Please confirm, the eviction thread DOES NOT use the transaction manager at all, either for reading or writing. The eviction thread does not execute in the context of a JTA transaction.
As you can see from the logs I posted the "write lock could not be acquired" error is logged on the same thread (Thread-31) as eviction policy is running on. This means the eviction thread is trying to establish some lock. I just assumed this was a transaction lock, but it must be some internal locking mechanism on the local node only. Please confirm this.
I just assumed this was a transaction lock
No, its not a transaction lock. JBossCache uses an internal mechanism of locking objects(i think it uses a Map to maintain ojects that it "locks". In simple terms, this is just a logical lock.)