db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ilan Kirsh <ki...@objectdb.com>
Subject Re: Proposal for new method (long)
Date Mon, 09 Oct 2006 19:49:35 GMT
Hi Craig,

This proposal reminds me the proxy EntityManagers that a Java EE 5 container can use, which
mean that my post yesterday regarding automatic injection of JEntityManager was probably too
naive. Maybe the new proxy PersistenceManager can also help somehow in injection of a PersistenceManager
in a Java EE 5 container? Also, it might make sense to implement such a proxy (or most of
its activity) on the JDO side rather than by every implementation (I guess that at least other
vendors may agree with that). Therefore the right location for a new method might be in JDOHelper.

Regards,

Ilan

  ----- Original Message ----- 
  From: Craig L Russell 
  To: Apache JDO project ; JDO Expert Group 
  Sent: Monday, October 09, 2006 7:58 PM
  Subject: Proposal for new method (long)


  Javadogs, 


  I'd like to propose a solution to a problem that we have with usability in the web tier.
When using a servlet, each method that needs access to a PersistenceManager needs to figure
out where the current PersistenceManager is, and if it is even active. There are many ways
around this issue, but they are not general. Among the workarounds are putting the active
PersistenceManager into the servlet context as a request or session attribute, passing the
PersistenceManager explicitly as a parameter, and putting the PersistenceManager into a ThreadLocal
field. 


  Of these workarounds, the one with the most appeal is the ThreadLocal solution. So I'd like
to propose that we formalize this by adding a method to return a thread-safe PersistenceManager
proxy associated with a PersistenceManagerFactory that can be implemented as a singleton,
stored in a component's static field, and that dynamically binds to the PersistenceManager
that is currently active on the thread.


  Multiple PersistenceManager proxies can be active, each with its own binding to a (possibly
different) PersistenceManagerFactory.


  The benefit of this proposal is ease of use for web and ejb components that currently have
to manage their own PersistenceManager resources. Instead of having to look up and store a
PersistenceManager in each method of each component that needs one, looking up the PersistenceManagerFactory
can be done once during initialization of the component.


  The limitations of the proposal is that in environments that do not support Java EE 5 TransactionSynchronizationRegistry
(i.e. J2SE servers and Java SE), only one PersistenceManager per PersistenceManagerFactory
can be used per thread (which maps to a single web request), and only one transaction can
be used per PersistenceManager.


  In environments that support Java EE 5 TransactionSynchronizationRegistry, container-managed
transactions can be used, including the ability to suspend transactions. 


  If used in an environment that does not support Java EE 5 TransactionSynchronizationRegistry,
the behavior is as follows:


  The first component to use a PersistenceManager method on a thread would get a PersistenceManager
from the factory. Subsequent callers would use the same PersistenceManager delegate until
the transaction completed, at which time the PersistenceManager is cleared and the first subsequent
request would create a new one.


  Implementation: The proxy would delegate most methods to the current PersistenceManager,
as determined by the ThreadLocal field being non-null. Calling close() would have no effect.
If the ThreadLocal field is null, then getPersistenceManager() would be called on the PersistenceManagerFactory.
A synchronization instance would be created and registered with the currentTransaction of
the newly acquired PersistenceManager, the PersistenceManager would be set into the ThreadLocal,
and then the request wold be delegated to the new PersistenceManager. At afterCompletion,
the ThreadLocal would be nullified.


  If used in an environment that supports Java EE 5 TransactionSynchronizationRegistry, the
behavior is as follows:


  The first component to use a PersistenceManager method in a managed transaction would get
a PersistenceManager from the factory. Subsequent callers in the same transaction would use
the same PersistenceManager delegate until the transaction completed, at which time the PersistenceManager
is cleared and the first request in a new transaction would create a new one.


  Implementation: The proxy would delegate most methods to the current PersistenceManager,
as determined by the TransactionSynchronizationRegistry entry for the PersistenceManagerFactory
being non-null. Calling close() would have no effect. If the TransactionSynchronizationRegistry
entry for the PersistenceManagerFactory is null, then getPersistenceManager() would be called
on the PersistenceManagerFactory. An interposed synchronization instance would be created
and registered with the TransactionSynchronizationRegistry, the PersistenceManager would be
set into the TransactionSynchronizationRegistry entry for the PersistenceManagerFactory, and
then the request wold be delegated to the new PersistenceManager. At afterCompletion, the
TransactionSynchronizationRegistry entry for the PersistenceManagerFactory would be nullified.


  If we agree on the semantics of this behavior, the method can be implemented as a helper
method of JDOHelper, PersistenceManager getPersistenceManagerProxy or something like it (suggestions
welcome).


  To support container-managed transactions in J2EE servers (1.4 and earlier), we would have
to put the method on PersistenceManagerFactory and allow the implementation to use its own
secret sauce to provide the proper semantics. If the jdo implementation chose, it could simply
delegate to the JDOHelper version of the method, with the limitations therein.


  Craig


  Craig Russell

  Architect, Sun Java Enterprise System http://java.sun.com/products/jdo

  408 276-5638 mailto:Craig.Russell@sun.com

  P.S. A good JDO? O, Gasp!



Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message