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: gordon yorke <gordon.yorke_at_oracle.com>
Date: Wed, 13 Mar 2013 22:13:44 -0300

I do not object as this is an improvement on what we have today.
--Gordon

On 13/03/2013 6:55 PM, Linda DeMichiel wrote:
> I think this is reasonable. Do any of you object to such language
> being added to the spec?
>
> On 3/13/2013 12:10 PM, Scott Marlow wrote:
>> On 03/13/2013 02: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.
>>
>> For 7.9.1, how about something like:
>>
>> "
>> After the JTA transaction has completed (either by transaction commit
>> or rollback), the container closes the entity
>> manager by calling EntityManager.close. The JTA transaction may
>> rollback in a background thread (e.g. transaction
>> timeout), in which case, the container should arrange for the entity
>> manager to be closed but the EntityManager.close()
>> should not be concurrently called while the application is in an
>> EntityManager invocation.
>> "
>>
>> The 7.9.2 wording can be similar I think:
>> "
>> 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. The JTA transaction may rollback in a
>> background thread (e.g. transaction timeout), in which case, the
>> provider should arrange for the managed entities to be
>> detached from the persistence context but not concurrently while the
>> application is in an EntityManager invocation.
>> "
>>
>>>
>>> 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
>>>>
>>