Craig L Russell <Craig.Russell <at> Sun.COM> writes: > > Hi Guido, > > Thanks for your comments. > > On Feb 12, 2007, at 4:39 AM, Guido Anzuoni wrote: > > > It is not clear when the real PersistenceManager will get closed. > > In a RESOURCE_LOCAL scenario close on the proxy could be propagated > > to the > > real PM before/after > > deassociation in the Thread-local > > Yes, this is a good idea and I'll incorporate this into the > specification. > > > (why an implementation specific variable ? > > Is it really needed to be implementation specific ?) > > The reason to specify the precise ThreadLocal would be to allow users > to access it directly. We would have to specify the class and > accessors for the field. This would complicate the specification, > which is intended to be "just specific enough" to give users > everything they want without the possibility of hurting themselves. > > > In a JTA scenario things get a little complicated. > > The real PM could be closed by a Synchronization.afterCompletion() > > registered byPersistenceManagerProxy > > Actually, the real PM would be closed by the afterCompletion > registered by the real PersistenceManager. The real > PersistenceManager is automatically de-registered by the behavior of > TransactionSynchronizationRegistry if that interface is used by the > implementation, or by an implementation-specific mechanism. > > > when > > it associate the PM with the transaction, but there could be > > ordering issues > > with other Synchronization objects referencing > > the same PM. > > I believe that this scenario is covered already in the specification. > The PM is responsible to call the user's registered Synchronization > instance during transaction completion. The proxy does not complicate > this existing usage.
Well, maybe it's too late, but, you know, thinking process might take some time :) I have some extra comments on closing PM in a JTA scenario. You say that actually the real PM is closed by the afterCompletion registered by the real PersistenceManager. I disagree on this. PersistenceManager outlives the transaction boundaries, either global or local. You can have the following usage: PersistenceManager pm = ... UserTransaction ut = ... ut.begin(); pm.makePersistent(); ut.commit(); ... ut.begin(); pm.makePersistent(); ut.commit(); .. pm.close(); In a proxy-based scenario the real PM has a lifecycle that is completely bound to the (global) transaction lifespan: it is created when the user requires a PM the first time and is closed by the proxy upon completion (Synchronization.afterCompletion on the JTA transaction). This lead to the assumption that: 1. no PM (proxy) can be acquired without an open JTA transaction 2. Synchronization.afterCompletion of the proxy should be called **after** any other Synchronization that might be registered by the real implementation on the JTA transaction itself (this is critical because JTA does not enforce any ordering in Synchronization objects). An alternative to guarantee that the proxy Synchronization.afterCompletion is invoked after any "finalization" actions performed by the PM, is to register the synchro on pm.currentTransaction(), but this would "consume" the only slot available. This would not be a big problem, because the real pm remains almost hidden to the app (unless JDOHelper.getPersistenceManager(o) is called). What I like is the JDO implementations being unaware of PersistenceManagerProxy, so it is responsibility of the proxy to close the real pm. Guido.