jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: unsynchronized persistence contexts

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Fri, 02 Sep 2011 11:05:29 -0300

> 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?]
Hello All,
   I have been thinking about this issue for a while and believe it is unsafe to allow a *joined* EXTENDED UNSYNC'd PC to be *inherited* by a component using a SYNC'd PC. The UNSYNC'd PC would become bound to that component and that would be technically incorrect. We could allow the propagation of *joined* TRANSACTION UNSYNC'd PCs to SYNC'd PCs but that may be too confusing for users.

On 8/26/2011 4:00 PM, 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.
>
> 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?]
>
>
>