db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Re: detachOnCommit + J2EE / detachOnClose
Date Thu, 02 Mar 2006 16:38:29 GMT
Hi Marco,

On Mar 2, 2006, at 1:19 AM, Marco Schulze wrote:

> Hello JDO team,
>
> I just came back from holidays and it seems I'm too late as you  
> already voted. But still, I'd like to mention an issue about the  
> feature detachOnCommit: When using a JDO implementation within a  
> J2EE server, this feature IMHO doesn't make much sense, because the  
> transaction might be committed/rolled back later than the object  
> needs to be detached. This is especially true when using XA  
> transactions. Additionally, it is possible (at least some JDO  
> implementations support it) to read data without having any  
> transaction (i.e. non-transactional read).
>
> In both cases, it would be necessary to have additionally a  
> detachOnClose feature. Means, whatever happens first (commit  
> transaction or close persistence manager) should cause the objects  
> to be detached.
>
> To make things clearer, I'd like to shortly explain the handling  
> difference between non-J2EE and J2EE: When using JDO outside a  
> managed environment, the workflow works like this:
>
>   1. open the persistence manager
>   2. open a transaction
>   3. work with JDO objects
>   4. commit/rollback the transaction
>   5. close the persistence manager
>
> All the above steps are performed explicitely by the programmer.
>
> Within a J2EE container (i.e. within an EJB method), things are  
> different:
>
>   1. J2EE opens a transaction for you _implicitely_ (the transaction
>      might involve many servers; thus it might already exist before  
> the
>      EJB method is triggered)
>   2. obtain a persistence manager

In this scenario, the JDO implementation must guarantee that the  
PersistenceManager obtained by  
PersistenceManagerFactory.getPersistenceManager() is a proxy to the  
PersistenceManager enlisted in the transaction.

>   3. work with JDO objects
>   4. close the persistence manager

This is where I think the misunderstanding is. Until the transaction  
in which the PersistenceManager is enlisted commits, you must not  
close the PersistenceManager. Therefore, the object that you give to  
the user cannot be the real PersistenceManager; it must be a proxy to  
the real PersistenceManager. When the user closes the proxy, the real  
PersistenceManager stays open until the TransactionManager commits  
the transaction. That's when the DetachAllOnCommit behavior takes place.

>   5. J2EE commits/rolls back the transaction _implicitely_
>
> A JDO object will be sent to the client using native serialization  
> either between 4 and 5 (with XA transactions) or after 5 - though  
> I'm not completely sure, it might be always between 4 and 5 even  
> with local transactions.
>
> JPOX fortunately already supports detachOnClose as a vendor  
> extension, but IMHO this feature deserves to be integrated into the  
> JDO standard.

Unfortunately, when the PersistenceManager is closed, there cannot be  
an active transaction. Therefore, there might not be an opportunity  
for the PersistenceManager to obtain a connection to the underlying  
transactional resource. And so there is no way to implement the  
detachment contract.

To clarify my point, here's how I see the J2EE scenario working:

   1. J2EE opens a transaction for you _implicitely_ (the transaction
      might involve many servers; thus it might already exist before the
      EJB method is triggered)

   2. obtain a persistence manager -  
PersistenceManagerFactory.getPersistenceManager(). If this is the  
first call by a component in this transaction, create a new  
PersistenceManager and register it with the  
TransactionSynchronizationRegistry via the putResource 
(persistenceManagerFactory, persistenceManager) call. Register a  
synchronization callback via TransactionSynchronizationRegistry   
registerInterposedSynchronization(Synchronization sync) where the  
sync object is bound to the PersistenceManager. Create a new  
PersistenceManager proxy, bind it to the newly created  
PersistenceManager, and return the proxy to the user.

   3. work with JDO objects
   4. close the persistence manager - close the proxy. Mark it as  
closed, and disallow further method calls on it except for isClosed,  
close(), and get methods.

4a. In a different component, obtain a persistence manager  
PersistenceManagerFactory.getPersistenceManager(). Since this is not  
the first call by a component in this transaction, call  
TransactionSynchronizationRegistry getResource 
(persistenceManagerFactory) which finds the PersistenceManager  
already registered with the TransactionSynchronizationRegistry via  
the previous putResource(persistenceManagerFactory,  
persistenceManager) call. Create a new PersistenceManager proxy, bind  
it to the found PersistenceManager, and return the proxy to the user.

4b. work with JDO objects

4c. close the persistence manager - close the proxy. Mark it as  
closed, and disallow further method calls on it except for isClosed,  
close(), and get methods.

   5. J2EE commits/rolls back the transaction _implicitely_ The  
PersistenceManager callback registered in 2 above is called for  
beforeCompletion and afterCompletion of the transaction. Since this  
is an interposed synghronization, it is called before the  
ResourceAdapter synchronizations (jdbc Connection and other Connector  
implementations) so the PersistenceManager can flush its changes to  
the underlying Connection. During this callback, the  
PersistenceManager performs the actions required by DetachAllOnCommit  
in terms of fetching FetchPlan objects from the database. After all  
of the synchronization beforeCompletion callbacks are executed, the  
normal 2 phase commit happens to the underlying Connections. During  
the afterCompletion callback, the rest of the DetachAllOnCommit  
behavior occurs, which is the actual detachment of the persistent  
instances and the nullification of the relationship fields that are  
not part of the FetchPlan.

Best,

Craig

>
> Best regards, Marco :-)
>
> -- 
> ______________________________________________
> Marco Schulze                   NightLabs GmbH
>                                Rehlingstr. 6d
>                                79100 Freiburg
>                                Germany
>
> eMail:  Marco@NightLabs.de
> Fon:    +49-761-2 111 793
> Fax:    +49-761-2 111 798
> WWW:    http://www.NightLabs.de
>
> Geschäftsführung:
>  Marco Schulze <Marco@NightLabs.de>
>  Niklas Schiffler <Nick@NightLabs.de>
>
> Eintragung:
>  Amtsgericht Freiburg, HRB 6186
> ______________________________________________
>

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
View raw message