Hi Ricardo,
Short Answer: ------------------ Yes, it is necessary to lock/unlock in background threads when safeLocking=true. ERXEC auto *unlocking* occurs in request/response threads, not background threads. IIRC auto *locking* happens when any methods in ERXEC are called directly (or indirectly) by your using it.
Long Answer: ---------------- If safeLocking = true, your ERXEC's get locked when they are "touched". ERXEC "remembers" that lock in a ThreadLocal, a variable associated with the current thread. You can see how this works if you look at the source for ERXEC.
The unlocking of all ERXEC's that were locked in the current thread happens when ERXEC.unlockAllContextsForCurrentThread() is called *by someone*. This happens for you automatically in normal R-R loop in ERXApplication._endRequest().
If you use ERXExecutorService.executorService().execute( runnable ) OR ERXExecutorService.executorService().submit( ... ), your background task is automatically executed in a thread belonging to an instance of ERXTaskThreadPoolExecutor which automatically calls ERXEC.unlockAllContextsForCurrentThread() in the same thread as your task ran after your task is finished. *However*, IMHO, in the context of background threads, this should only be acknowledged as a safety net, rather than a mechanism to ignore EC locking such as we do in R-R threads when we have safeLocking turned on.
So my general rule is: manually lock/unlock in background threads.
BTW, if you decide not to manually lock/unlock and you architect things such that ERXEC.unlockAllContextsForCurrentThread() is called at the end of a task, you have to think about all the locked EC's you might have sitting around. Imagine if you are processing 50 million EOs and recycling EC's in batches of 500 and depending on one single moment where all locked EC's get unlocked at the end of the task ... do you think you will have enough memory for 100,000 EC's still locked, or would memory be better if you unlock each EC after using it and let if get garbage-collected during the very long time that the task runs?
Regards, Kieran
On Mar 22, 2011, at 12:11 PM, Ricardo J. Parada wrote: On Mar 22, 2011, at 8:50 AM, Kieran Kelleher wrote: You *should* lock in background threads.
ERXEC notificationtEC = (ERXEC) ERXEC.newEditingContext(objectStoreCollection.nextObjectStoreCoordinator()); notificationtEC.lock(); try { // do stuff
notificationtEC.saveChanges(); } catch (Exception e) { log.error("We had an unexpected error in background thread blah blah blah....", e); } finally { notificationtEC.unlock(); }
Hi Kieran,
Is this necessary for background thread if Wonder is configured with er.extensions.ERXEC.safeLocking=true ?
Or is that why you said *should* ?
:-)
Thanks, Ricardo
|