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: Ireland, Evan <evan.ireland_at_sap.com>
Date: Thu, 14 Mar 2013 00:49:17 +0000

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
>>>
>