jsr338-experts@jpa-spec.java.net

[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:14:04 -0300

There is nothing in the spec now preventing a container from closing an
EntityManager before the end of the bean method invocation or user
transaction commit so IllegalStateExceptions could happen now. If
preventing the close() is needed then that would need additional
language likely something similar to what you propose.
--Gordon
On 13/03/2013 9:49 PM, Ireland, Evan wrote:
> I think I do object, for the reason I indicated in my separate email. That is, with the proposed change, now the IllegalStateExceptions may crop up even though the application thread using the EntityManager has not made a mistake in API usage.
>
> -----Original Message-----
> From: Linda DeMichiel [mailto:linda.demichiel_at_oracle.com]
> Sent: Thursday, 14 March 2013 10:55 a.m.
> To: jsr338-experts_at_jpa-spec.java.net
> Cc: Scott Marlow
> Subject: [jsr338-experts] Re: transaction-scoped persistence context being closed at JTA transaction completion time from non-application thread ...
>
> 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