jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: unsynchronized persistence contexts

From: Linda DeMichiel <linda.demichiel_at_oracle.com>
Date: Thu, 08 Sep 2011 15:01:16 -0700

On 9/8/2011 1:45 PM, Evan Ireland wrote:
> Linda,
>
> You wrote:
>
>> I think that binding EPCs to singletons is potentially
>> useful; inheritance
>> not so much.
>
> I'm not sure that I agree. The primary use case that I am aware of for EPC's
> is for session-related persistence.
>
> If someone can give a use case for the use of EPC's with singletons, I would
> like to hear it.
>

For reference data.


>> -----Original Message-----
>> From: Linda DeMichiel [mailto:linda.demichiel_at_oracle.com]
>> Sent: Friday, 9 September 2011 6:44 a.m.
>> To: jsr338-experts_at_jpa-spec.java.net
>> Cc: Gordon Yorke
>> Subject: [jsr338-experts] Re: unsynchronized persistence contexts
>>
>> At this point, I think the safest course of action here is
>> the conservative
>> one, and not to proceed with changes to the inheritance
>> rules, at least
>> until we get further feedback in this regard.
>>
>> If you feel strongly about this issue, please let me know.
>>
>> I have also been thinking about singletons, which were left as an open
>> issue in the proposal I circulated.
>>
>> Inheritance of PCs by singleton's is also problematic, independent of
>> whether they are synchronized or not.
>> The EJB spec states that singleton's are created by the container,
>> not directly by the application. This creation may be at startup
>> (and is required to be if the @Startup annotation has been applied),
>> or it may be deferred, as late as the first method invocation upon
>> the singleton. The time of the creation of a singleton is also
>> influenced by whether any other singleton has a @Depends relationship
>> upon it.
>>
>> We thus cannot assume that a singleton that is not marked @Startup
>> should inherit a PC (as the rules below proposed for method invocation
>> time inheritance for SLSBs), as that singleton may have been created
>> at startup time as well. So, my conclusion is that a singleton should
>> not inherit a PC.
>>
>> That leaves the issue of whether EPCs should be bound to singletons,
>> and, if so, whether such EPCs should be inherited by beans which
>> the singleton instantiates.
>>
>> I think that binding EPCs to singletons is potentially
>> useful; inheritance
>> not so much.
>>
>> Should we extend the notion of *binding* an EPC to a singleton??
>>
>> -Linda
>>
>>
>> On 9/2/2011 7:05 AM, Gordon Yorke wrote:
>>>> 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?]
>>>>
>>>>
>>>>
>>
>