jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: unsynchronized persistence contexts

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Fri, 09 Sep 2011 15:01:01 -0300

> the resulting behavior is as if the PC is propagated.
It is a "hole" that EPCs can not be accessed from within a SLSBs outside of a transaction and it is a limitation that should be resolved. The reality is a PC is never really propagated to the SLSB anyway but is assigned to the transaction and resolved by the container. With an EPC the container will still resolve the reference but the EPC will be propagated along the call stack. Perhaps we just need to use different language to make it less confusing. Perhaps describing the curent inheritance as propagation via call stack or thread would help to align the behaviours.

--Gordon



On 9/9/2011 2:12 PM, Linda DeMichiel wrote:
>
>
> On 9/8/2011 12:27 PM, Gordon Yorke wrote:
>> Inline:
>>
>> On 9/8/2011 3:43 PM, Linda DeMichiel wrote:
>>> 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.
>> Except the change that allows an EPC to be inherited by a Stateless Session Bean?
>
> Yes, this is the case I'm struggling with. At this point, I'm
> questioning whether we should do that (at least now), or whether it
> would just be confusing, given that the "inheritance" would be for the
> duration only a a method call. The main advantage I see for it over the
> current spec + the proposal for propagation is that in the absence of
> a tx, the resulting behavior is as if the PC is propagated.
>
>
> And we need additional restrictions to
>> prevent inheritance of PC with different transaction participation requirements.
>
> Yes.
>
>>>
>>> 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.
>> Agreed.
>>>
>>> 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.
>> Inheritance here is important for the same reasons it is include for Statefull Session Beans; users want the PC to be
>> consistent across the call stack.
>> We may want to add to section 7.2 to note special care should be taken when using EPCs in Stateless Session Beans and
>> Singleton Session Beans.
>>>
>>> Should we extend the notion of *binding* an EPC to a singleton??
>> We should treat it as a Statefull Session Bean with the exception that a EPC is assigned when it is created.
>>>
>>> -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?]
>>>>>
>>>>>
>>>>>