users@jpa-spec.java.net

[jpa-spec users] [jsr338-experts] Re: transaction-scoped persistence context being closed at JTA transaction completion time from non-application thread ...

From: Steve Ebersole <steve.ebersole_at_redhat.com>
Date: Wed, 13 Mar 2013 14:53:47 -0500

If anyone is interested, the background and discussions for this can be
found at:

https://hibernate.onjira.com/browse/HHH-7910

and

https://github.com/hibernate/hibernate-orm/pull/476

As for what various providers do, we take an approach in Hibernate where:
1) While handling a sync callback, we check to see if the thread of
execution is the same as the last known "main line" call into the EM.
If it is not, we set a flag and stop processing the sync callback (for
the SUCCESS case we just let the execution proceed regardless because
for Hibernate there is no danger in that case).
2) Upon entry and exit from every public facing EM method we check that
flag and process the "after completion" processing if needed. Why entry
and exit? Because we like to be through :) The exit checks explicitly
handle *concurrent calls* to the EM through the sync (while a call is in
flight within the EM back on the application thread); the entry calls
handle a slightly different, though related, case mainly in in-container
execution.


On 03/13/2013 01:15 PM, Linda DeMichiel wrote:
> Hi Scott,
>
> On 3/13/2013 11:04 AM, Scott Marlow wrote:
>> Are others responding privately perhaps? :)
>>
>
> No. I wish they were responding in *any* manner!
>
>
>> At a minimum, I would like to state that the JTA transaction could be
>> rolled back from an external thread in the
>> following sections:
>>
>
> As you point out, the JTA spec already allows this, so if that is all
> we were to do, I'm not sure I
> see the point. In case I am being dense though, can you tell me what
> words you would like to see added to
> the spec.
>
> To me, the real issue seems to be whether we can/should provide any
> guidance as to how to handle such
> situations. I'd like to get the benefit of hearing from the vendors
> here as to what their implementations
> do.
>
> thanks,
>
> -Linda
>
>
>> The current wording is:
>>
>> "
>> 7.9.1 Container Responsibilities
>> ...
>> * After the JTA transaction has completed (either by transaction
>> commit or rollback), the container closes the entity
>> manager calling EntityManager.close.
>> ...
>>
>> 7.9.2 Provider Responsibilities
>> ...
>> * When the JTA transaction rolls back, the provider must detach all
>> managed entities if the persistence context is of
>> type SynchronizationType.SYNCHRONIZED or has otherwise been joined to
>> the transaction.
>> ...
>> "
>>
>>
>> On 03/08/2013 08:31 PM, Linda DeMichiel wrote:
>>>
>>>
>>> On 3/7/2013 4:48 PM, Scott Marlow wrote:
>>>> On 03/07/2013 05:41 PM, Linda DeMichiel wrote:
>>>>>
>>>>>
>>>>> On 3/6/2013 2:16 PM, Scott Marlow wrote:
>>>>>> [1] requires that at Transaction completion, the container closes
>>>>>> (or
>>>>>> returns to cache), the transaction-scoped
>>>>>> persistence context. What is supposed to happen when the JTA
>>>>>> transaction completes in a different thread than the
>>>>>> application thread? For example, if a background thread calls the
>>>>>> Synchronization.afterCompletion() because the tx
>>>>>> timeout period has been exceeded (as some Transaction Managers may
>>>>>> do), its not exactly thread-safe to call
>>>>>> EntityManager.close() (see [2]). Specifically, the application could
>>>>>> be in the middle of a persist or some other
>>>>>> EntityManager method, when EntityManager.close() is called.
>>>>>>
>>>>>
>>>>> The team here tells me that this should not be happening, and that
>>>>> the
>>>>> transaction managers they are
>>>>> familiar with will just mark the transaction for rollback rather than
>>>>> rolling it back at the point
>>>>> of timeout.
>>>>
>>>> Currently, we roll the transaction back from the background timer
>>>> thread. The JTA spec [4] does allow different threads
>>>> to start/end the transaction.
>>>>
>>>
>>> Yes, I realize this is permitted.
>>>
>>>>>
>>>>> Nevertheless, if the container were working with a TM where a timeout
>>>>> did result in immediate
>>>>> rollback and invocation of afterCompletion, the container should note
>>>>> this, and at the point at
>>>>> which the transaction would normally be completed then do the actual
>>>>> close as it normally would.
>>>>
>>>> Should we include a form of the above text in the JPA 2.1 spec
>>>> (section 7.9.1 [1])?
>>>>
>>>
>>> Unfortunately, I don't think this may always work, because the
>>> container may be relying on synchronization notifications at the
>>> normally expected tx end to know when it should be calling close
>>> (i.e., it may not know when the tx was started). If EJB CMT were
>>> used, the container would know when a tx was started and could use a
>>> business method boundary as the interpositioning point. If a
>>> container wrapped UserTransaction, I suppose it could use that point
>>> as well, but it is not obvious to me how this would be handled
>>> otherwise.
>>>
>>> How does your implementation handle this?
>>>
>>> I'd also like to hear from the other implementations here as to
>>> what they do and how their transaction manager implementations
>>> handle timeout.
>>>
>>>
>>>> How would we word what the provider side has to do when detaching
>>>> entities after rollback [3]? I'm not sure that the
>>>> persistence provider will have the same chance to make a note for the
>>>> container side to take action on (if there is an
>>>> EE container involved). There is also the expectation that any JPA
>>>> provider will work, with any EE container to consider.
>>>>
>>>>>
>>>>> What do your transaction manager and container do?
>>>>>
>>>>>> Related to the above, if a JTA transaction rollback occurs in a
>>>>>> background thread [3], how are the managed entities
>>>>>> expected to be detached without violating the EntityManager
>>>>>> thread-safety [2]?
>>>>>>
>>>>>> There may be vendor specific solutions but shouldn't we (JPA spec
>>>>>> eg)
>>>>>> account for the interaction of thread-unsafe
>>>>>> persistence contexts and the JTA Synchronization.afterCompletion
>>>>>> that
>>>>>> may be invoked in non-application (background)
>>>>>> threads?
>>>>>>
>>>>>> Scott
>>>>>>
>>>>>> [1] 7.9.1 Container Responsibilities - After the JTA transaction has
>>>>>> completed (either by transaction commit or
>>>>>> rollback), the container closes the entity manager calling
>>>>>> EntityManager.close.
>>>>>>
>>>>>> [2] 7.2 Obtaining an EntityManager - An entity manager must not be
>>>>>> shared among multiple concurrently executing threads,
>>>>>> as the entity manager and persistence context are not required to be
>>>>>> threadsafe. Entity managers must only be accessed
>>>>>> in a single-threaded manner.
>>>>>>
>>>>>> [3] 7.9.2 Provider Responsibilities - When the JTA transaction rolls
>>>>>> back, the provider must detach all managed entities
>>>>>> if the persistence context is of type
>>>>>> SynchronizationType.SYNCHRONIZED
>>>>>> or has otherwise been joined to the transaction.
>>>>
>>>> [4] JTA 1.1 spec 3.4.3 Thread of Control:
>>>>
>>>> "
>>>> The X/Open XA interface specifies that the transaction association
>>>> related xa calls must be invoked from the same thread
>>>> context. This thread-of-control requirement is not applicable to the
>>>> object-oriented component-based application
>>>> run-time environment, in which application threads are dispatched
>>>> dynamically at method invocation time. Different Java
>>>> threads may be using the same connection resource to access the
>>>> resource manager if the connection spans multiple method
>>>> invocation. Depending on the implementation of the application server,
>>>> different Java threads may be involved with the
>>>> same XAResource object. The resource context and the transaction
>>>> context may be operated independent of thread context.
>>>> This means, for example, that it’s possible for different threads to
>>>> be invoking the XAResource.start and XAResource.end
>>>> methods.
>>>>
>>>> If the application server allows multiple threads to use a single
>>>> XAResource object and the associated connection to the
>>>> resource manager, it is the responsibility of the application server
>>>> to ensure that there is only one transaction
>>>> context associated with the resource at any point of time.
>>>>
>>>> Thus the XAResource interface specified in this document requires that
>>>> the resource managers be able to support the
>>>> two-phase commit protocol from any thread context.
>>>> "
>>>>
>>>> Scott
>>