[jboss-jira] [JBoss JIRA] (WFLY-8954) Wildfly 10 with eclipselink Onscucess observer gets stale entity
Nuno Godinho de Matos (JIRA)
issues at jboss.org
Wed Jun 28 05:32:00 EDT 2017
[ https://issues.jboss.org/browse/WFLY-8954?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13427948#comment-13427948 ]
Nuno Godinho de Matos edited comment on WFLY-8954 at 6/28/17 5:31 AM:
----------------------------------------------------------------------
Hi,
It is a bit hard for me to keep up, as these APIs at the level of resource adapter developers and component integration.
But I see the point you bring up:
It is not such a trivial matter to manage the sequence by which Synchronization Listeners register on the JTA transaction context.
I believe however, that one way or another, somehow the eclipselink:
org.eclipse.persistence.transaction.JTASynchronizationListener
Needs to be run before the CDI on completion synchronization listener.
This a level of service with quite a bit of importance.
To not do violates the exceptions that developers have of what the state of the DB an cached entities should be as a transaction is said to be completed. And in fact, with hibernate this level of service is upheld.
Side Notes:
I am tried to take a pick the eclipse link code related to the synchronization process.
I can see that with the increasing versions, the code in eclipselink is gettingbetter and better documented. Which i consider something very positive.
Here are some of the relevant classes I have spotted, but most likely you are aware of them all.
org.eclipse.persistence.transaction.JTATransactionController
This class is extended by multiple subclasses, specific to different application servers.
Among its apis it holds the method:
registerSynchronization_impl
QUOTE
{panel}
/**
* INTERNAL:
* Register the specified synchronization listener with the given active
* transaction.
*
* @param listener The synchronization listener created for this transaction
* @param txn The active transaction for which notification is being requested
*/
protected void registerSynchronization_impl(AbstractSynchronizationListener listener, Object txn) throws Exception {
((Transaction)txn).registerSynchronization((Synchronization)listener);
}
{panel}
NOTE: And here we know that the registration will be happening too late.
With the WildflyServerPlaform,
{panel}
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>jipijapa-eclipselink</artifactId>
<version>10.0.0.Final</version>
<scope>provided</scope>
</dependency>
{panel}
it would look to me as if the ideal spot to do the tunning would be on:
org.jipijapa.eclipselink.WildFlyServerPlatform.JBossAS7TransactionController
If this class could somehow override the registerSynchronization_impl to ensure that when it registers it goes to earlies position on the list.
But from what I can see, at leas t from public APIs, there seems to be no support
to do anything such as manipulating the order of the listeners.
There is also the the class
org.eclipse.persistence.internal.jpa.EntityManagerImpl
This the class that takes us down the rabbit hole,
and that will do the JTA synchronization registration listener is put in place in its:
org.eclipse.persistence.internal.jpa.EntityManagerImpl.getActivePersistenceContext(Object)
{panel}
if (txn != null) {
// if there is a txn, it means we have been marked to join with it.
// All that is left is to register the UOW with the transaction
transaction.registerIfRequired(this.extendedPersistenceContext);
}
{panel}
I will now mention two possibilities, that I believe none of them are feasible.
Any way, let me gun sling them away.
Possbility 1,
I would call it a "vodoo" work-around.
Ant that most likely is no feasible as explained bellow.
At time 1, when Wildfly registers the normal CDI Dummy synchronization listener - DelayedCDIObserverSynchronizationListenerr or something of the sort
At time 2, the arjuna is going over registered listeners and invoking them
com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(int) line: 96
At time 3, the DelayedCDIObserverSynchronizationListenerr
gets called and it makes a late registrations into the transaction of the real CDI listener that is currently being invoked in first place.
At time 4, the eclipselink
org.eclipse.persistence.transaction.JTASynchronizationListener
At time 5, the real CDI Observer notifier gets invoked since it was "vodoo" placed into the trasaction at the alst posisble moment in time.
I can well imagine that this sort of work-around might not even be technically possible since it would verily likely lead to something like at concurrent modification exceptions on the:
com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(int) line: 96
As we goes out of invoking the listener, and tries to move to the next one, the list is suddenly changed and the loop broken.
But the fact is that the:
javax.transaction.Transaction registerSynchronization seems to give no option on sorting the order of the observers.
Also seems not to give any option to remove the observers.
Possibility 2 (might not be posisblle as well):
But this would be much much cleaner.
One would want to override method of:
registerSynchronization_impl
And write it to be something as simple as:
To (a) Get a list of all registered observers.
(b) Derisgeter them all
(c) Register the eclipselink obverserver first on the list
(d) Ad all of the de-registered observers back in.
Kindest regards.
was (Author: nuno.godinhomatos):
Hi,
It is a bit hard for me to keep up.
But I see the point.
It is not a trivial matter manage the sequence by which Synchronization Listeners register on the transaction.
But I would agree, that one way or another, somehow the eclipselink:
org.eclipse.persistence.transaction.JTASynchronizationListener
Needs to be run before the CDI on completion synchronization listener.
Side Notes:
- I am trying take a pick the eclipse link code related to the synchronization process.
Here are some of the relevant classes:
(a) org.eclipse.persistence.transaction.JTATransactionController
This class is extended by multiple subclasses, specific to different application servers.
Among its apis it holds the method:
registerSynchronization_impl
QUOTE
{panel}
/**
* INTERNAL:
* Register the specified synchronization listener with the given active
* transaction.
*
* @param listener The synchronization listener created for this transaction
* @param txn The active transaction for which notification is being requested
*/
protected void registerSynchronization_impl(AbstractSynchronizationListener listener, Object txn) throws Exception {
((Transaction)txn).registerSynchronization((Synchronization)listener);
}
{panel}
And here we know that the registration will be happening too late.
With the WildflyServerPlaform, it would like the ideal thing would be if the inner class:
org.jipijapa.eclipselink.WildFlyServerPlatform.JBossAS7TransactionController
Could somehow override the registerSynchronization_impl to ensure that when it registers it goes to earlies position on the list.
But I doubt there are public APIs for doing this level of tunning.
The class
org.eclipse.persistence.internal.jpa.EntityManagerImpl
Is that class that will go down the rabit hole, until the JTA synchronization registration listener is put in place in its:
org.eclipse.persistence.internal.jpa.EntityManagerImpl.getActivePersistenceContext(Object)
{panel}
if (txn != null) {
// if there is a txn, it means we have been marked to join with it.
// All that is left is to register the UOW with the transaction
transaction.registerIfRequired(this.extendedPersistenceContext);
}
{panel}
I could imagine the following Possbility 1,
That I could call a "vodoo" work-around.
Ant that most likely is no feasible as explained bellow.
At time 1, when Wildfly registers the normal CDI Dummy synchronization listener - DelayedCDIObserverSynchronizationListenerr or something of the sort
At time 2, the arjuna is going over registered listeners and invoking them
com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(int) line: 96
At time 3, the DelayedCDIObserverSynchronizationListenerr
gets called and it makes a late registrations into the transaction of the real CDI listener that is currently being invoked in first place.
At time 4, the eclipselink
org.eclipse.persistence.transaction.JTASynchronizationListener
At time 5, the real CDI Observer notifier gets invoked since it was "vodoo" placed into the trasaction at the alst posisble moment in time.
I can well imagine that this sort of work-around might not even be technically possible since it would verily likely lead to something like at concurrent modification exceptions on the:
com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(int) line: 96
As we goes out of invoking the listener, and tries to move to the next one, the list is suddenly changed and the loop broken.
But the fact is that the:
javax.transaction.Transaction registerSynchronization seems to give no option on sorting the order of the observers.
Also seems not to give any option to remove the observers.
Therefore a cleaner Possibility 2 (might not be posisblle as well:
One would want to override method of:
registerSynchronization_impl
And write it to be something as simple as:
To (a) Get a list of all registered observers.
(b) Derisgeter them all
(c) Register the eclipselink obverserver first on the list
(d) Ad all of the de-registered observers back in.
Kindest regards.
> Wildfly 10 with eclipselink Onscucess observer gets stale entity
> ----------------------------------------------------------------
>
> Key: WFLY-8954
> URL: https://issues.jboss.org/browse/WFLY-8954
> Project: WildFly
> Issue Type: Bug
> Components: JPA / Hibernate
> Affects Versions: 10.0.0.Final
> Reporter: Nuno Godinho de Matos
> Assignee: Scott Marlow
>
> Hi,
> In widlfly there seems to be an important issue concerning CDI events and observing these events during onsuccess. At least while using eclipselink.
> When using wildfly 10.0.0.Final together with eclipselink, if an application modifies an entity A, fires an event stating entity A has been modified, and an observer consumes this event during transaction success.
> Then the observer will be working with stale entities that do not reflect the modifications done to the entity.
> A sample application for this issue is available in:
> https://github.com/99sono/wildfly10-observe-on-success-stale-entity
> The widlfly configuration xml for the sample application, is available in the application itself, as can be seen in the readme documentation.
> Many thanks for taking a look.
> Kindest regards.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
More information about the jboss-jira
mailing list