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:  [EMAIL PROTECTED]
Fon:    +49-761-2 111 793
Fax:    +49-761-2 111 798
WWW:    http://www.NightLabs.de

Geschäftsführung:
 Marco Schulze <[EMAIL PROTECTED]>
 Niklas Schiffler <[EMAIL PROTECTED]>

Eintragung:
 Amtsgericht Freiburg, HRB 6186
______________________________________________


Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:[EMAIL PROTECTED]
P.S. A good JDO? O, Gasp!

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to