jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: unsynchronized persistence contexts

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Thu, 08 Sep 2011 16:30:35 -0300

Hello Adam and others,
> - Is lazy loading of Entities from a SynchronizationType.UNSYNCHRONIZED without associated JTA transaction allowed?
Yes, it should be.

On 9/8/2011 12:47 PM, Adam Bien wrote:
> A great proposal.
> On 26.08.2011, at 21:00, Linda DeMichiel wrote:
>
>> When we solicited feedback on features for this release, one of the
>> discussions on the jsr-317 feedback list concerned the ability to
>> specify a persistence context that was not "synchronized" with regard
>> to transactions -- i.e., which did not respond to transaction
>> synchronization notifications. This would offer a cleaner alternative
>> to the manual flushmode which was decisively rejected by the JPA 1.0
>> expert group.
>>
>> JPA already has the notion of a persistence context that is
>> unsynchronized. This occurs when an application-managed persistence
>> context is created outside the scope of a JTA transaction, and the
>> application must notify the entity manager that the persistence
>> context is to be joined to a subsequently-started transaction by means
>> of the joinTransaction() method.
>>
>> The proposal below is a strawman proposal for unsynchronized
>> container-managed persistence contexts that Mike, Gordon,
>> and I have collaborated on.
>>
>> This proposal attempts to define synchronization as orthogonal to the
>> existing persistence context types and propagation rules. It loosens
>> some of the restrictions imposed by those types however.
>> In particular:
>> -- Entity managers for unsynchronized transaction-scoped persistence
>> contexts can be used to invoke the persist, remove, refresh, and
>> merge operations regardless of the presence of an existing transaction.
>> -- The notion of extended persistence context is loosened to include
>> the use of extended persistence contexts being "bound" to stateless
>> session beans in order to capture the ability to propagate extended
>> persistence contexts from stateful session beans to stateless
>> session beans outside of a transaction.
>>
>> Please post your feedback to the group, including on the open issues.
>>
>> thanks,
>>
>> -Linda
>>
>> -----------------------------------
>>
>> Proposal:
>>
>> A container-managed persistence context can be designated at its point
>> of creation to be unsynchronized by means of the synchronization
>> element of the PersistenceContext annotation. Both transaction-scoped
>> and extended persistence contexts may be designated as unsynchronized.
>>
>> @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
>> public @interface PersistenceContext {
>> String name() default "";
>> String unitName() default "";
>> PersistenceContextType type default TRANSACTION;
>> SynchronizationType synchronization default SYNCHRONIZED;
>> PersistenceProperty[] properties() default {};
>> }
>>
>> public enum SynchronizationType {
>> SYNCHRONIZED,
>> UNSYNCHRONIZED
>> }
>>
>> A persistence context of type UNSYNCHRONIZED is not enlisted in any
>> JTA transaction unless explicitly joined to that transaction by the
>> application.
>>
>> An unsynchronized persistence context is enlisted in a JTA transaction
>> and registered for subsequent transaction notifications against that
>> transaction by invoking the EntityManager joinTransaction() method.
>> The persistence context remains joined to (synchronized with) the
>> transaction until the transaction commits or rolls back. After the
>> transaction commits or rolls back, the persistence context will not be
>> synchronized with any subsequent transaction unless the joinTransaction
>> method is invoked in the scope of that subsequent transaction.
>>
>> A persistence context of type SynchronizationType.UNSYNCHRONIZED must
>> not be flushed to the database unless it is joined to a transaction.
>> Both the persistence provider and the application are prohibited from
>> flushing to the database until the point that a transaction has been
>> joined. The application's use of queries with pessimistic locks, bulk
>> updates/delete queries, etc. result in the provider throwing the
>> TBDException. (If the application has specified FlushMode.AUTO, it
>> must be ignored by the provider when executing queries.) [Open Issue:
>> should this be IllegalStateException or a new JPA exception?] After
>> the persistence context has been enlisted in the JTA transaction,
>> these operations are again allowed.
> - I would use a plain IllegalStateException.
>
> - Is lazy loading of Entities from a SynchronizationType.UNSYNCHRONIZED without associated JTA transaction allowed?
>
>
>
>> The application is permitted to invoke the persist, merge, remove, and
>> refresh entity lifecycle operations on an entity manager corresponding
>> to a unsynchronized transaction-scoped persistence context as well as
>> one corresponding to an unsynchronized extended persistence context
>> independent of whether a transaction is active.
>> Such changes in the persistence context can be flushed to the database
>> either explicitly by the application or by the provider after the
>> persistence context has been joined to a transaction. If flush() is
>> not explicitly invoked, flushing may be deferred until commit time
>> depending on the operations invoked (and the setting of
>> FlushModeType.)
>>
>> If an unsynchronized persistence context has not been joined to the
>> current JTA transaction, rollback of the JTA transaction will have no
>> effect upon the persistence context. It is recommended that the
>> persistence provider use a non-JTA datasource for an unsynchronized
>> persistence context that has not been joined to a JTA transaction to
>> alleviate the risk of integrating uncommitted changes into the
>> persistence context in the event that the transaction is later rolled
>> back.
>>
>> If an unsynchronized persistence context has been joined to the JTA
>> transaction, transaction rollback will cause the persistence context
>> to be cleared and all pre-existing managed and removed instances to
>> become detached. (See spec section 3.3.2.)
>>
>> When a JTA transaction exists, an unsynchronized persistence context
>> is propagated with that transaction according to the rules below (in
>> the section Requirements for Persistence Context Propagation)
>> regardless of whether the persistence context has been joined to that
>> transaction.
>>
>>
>> Container-managed Extended Persistence Contexts (See spec section
>> 7.6.2)
>>
>> The rules pertaining to extended persistence contexts are relaxed as
>> follows: Any EJB component may specify the use of an extended
>> persistence context. If the persistence context bound to a stateful
>> session bean is not inherited by any other component, it is the
>> responsibility of the container to close the persistence context when
>> the @Remove method of the stateful session bean completes (or the
>> stateful session bean instance is otherwise destroyed) or when the
>> method invocation completes (if the component is a stateless session
>> bean or message-driven bean). [OPEN ISSUE: still need to handle the
>> singleton session bean case.]
>>
>>
>> Inheritance of Extended Persistence Contexts (See spec section
>> 7.6.2.1.)
>>
>> If a component to which an extended persistence context is bound
>> instantiates a stateful session bean component (executing in the same
>> EJB container instance), which also specifies an extended persistence
>> context, the extended persistence context of the first component is
>> inherited by the second component and bound to it, and this rule
>> recursively applies--independent of whether transactions are active or
>> not at the point of the creation. If the second component is a
>> stateless session bean component that is invoked by a component to
>> which an extended persistence context is bound, the persistence
>> context is propagated into the that stateless session bean and bound
>> to it for the duration of the method invocation.
>>
>> If the persistence context has been initiated or inherited by any
>> stateful session bean, the container does not close the persistence
>> context until all such stateful session beans have been removed or
>> otherwise destroyed.
>>
>>
>> Requirements for Persistence Context Propagation
>> (See section 7.6.3.1)
>> All the requirements of section 7.6.3.1 still apply. (The word
>> "existing" in the second sub-bullet should be removed.)
>> In addition, the following is added to the last bullet point:
>>
>> Subject to the above requirements, a synchronized persistence context
>> or an unsynchronized persistence context may be propagated into a
>> component that specifies an unsynchronized persistence context. An
>> unsynchronized persistence context may only be propagated into a
>> component that specifies an unsynchronized persistence context. The
>> attempt to propagate an unsynchronized persistence context into a
>> component that specifies a synchronized persistence context causes the
>> EJBException to be thrown. [OPEN ISSUE: Is this the right exception?
>> Should we relax this if the PC has been joined to the transaction?]
>>
>>
>>
>