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: Linda DeMichiel <linda.demichiel_at_oracle.com>
Date: Wed, 13 Mar 2013 11:15:19 -0700

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
>