-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect "WARN Closing open connection prior to commit" when handling BEFORE_COMMIT event #18737
Comments
Could you please provide a reproducer? (a small Maven project reproducing the behavior out of the box) Thanks! |
Of course, hope this works. |
I confirm I get the warning by running @Sanne does it ring a bell? Do you know who would be the right person to look at this? |
Interesting, thanks I'll have a better look tomorrow. |
The thing here is that Hibernate closes the connections on |
Hello @HelvetiaAppDev. When looking at this, I saw that there are 3 To fix the ordering, changes are required in either or both Hibernate and Arc to change the way the My understanding is that the Arc synchronization should not be interposed and we need to make sure it's executed before Hibernate. It's important because, from what I remember, in that case it will still be possible to run the Hibernate synchronization in the case it's not yet registered. @mmusgrov @ochaloup Can any of you give some advice here? Do you know the reasons why the Arc synchronization is 'interposed'? |
@barreiro I think this was something which is managed in WildFly. What I can say the Hibernate uses the SynchronizationRegistryBasedSynchronizationStrategy in WildFly (https://github.com/wildfly/wildfly/blob/main/jpa/hibernate5/src/main/java/org/jboss/as/jpa/hibernate5/JBossAppServerJtaPlatform.java#L44) which means that the Hibernate synchronization is registered as interposed (https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/engine/transaction/jta/platform/internal/SynchronizationRegistryBasedSynchronizationStrategy.java#L29). On the other hand the Weld is registered as standard synchronization The WildFly processing in this case would be [Weld,Hibernate*,JCA**] where * is interposed synchronization and ** is post-interposed synchronization (with all that handling in WildFly there could be still some corner cases - jakartaee/cdi#467 - as the CDI event observers are a bit of a corner case, which is what my CDI guru @manovotn is happy to tell me anytime I ask him about this topic :-) I'm not sure why the Arc observers synchronization is interposed in Quarkus (@mkouba @manovotn ?) and maybe the Agroal will need some special handling as it's done for JCA in WildFly (?) |
FYI jakartaee/cdi#467 might be of interest as that issue requested that CDI events always run as interposed synchronizations but as pointed out in comment, the WildFly implement of Weld
In WildFly, we purposely invoke the JCA synchronization last so that database connections aren't closed before Hibernate calls connection.close(). JCA used to complain when Hibernate closed connections after JCA had closed them, so that was solved by ordering the synchronization invocation order. |
Hmm, you're right. Didn't even know we use interposed synchronization here. |
Hmm, apparently it was me who implemented it that way as can be seen in - #6581 |
Could you somehow let applications decide whether they want to use interposed or non-interposed synchronization? Then they can either use the default or change it. I prefer that applications use non-interposed so that application level syncs are called first for Synchronization#beforeCompletion() but that is also a change in (Arc) application level behavior. So, I'm also not sure which way should be default. |
I talked about this with @ochaloup and we came to a conclusion that Arc should use standard synchronization rather than interposed. One of the reasons being that this is really of a user-invoked synchronization rather than a container-invoked one which makes usage of interposed synch dubious. As to what is described in jakartaee/cdi#467 plus the configurable option - the CDI issue isn't completely legitimate request because there would first have to be adjustments on JTA spec side. From what I understood (@ochaloup will correct me if I am wrong), JTA cannot guarantee entity manager state at that point making this requirement a non-portable one anyway. Will send a PR to fix the Arc-side of this issue shortly. |
Thank you all. I'll retest this one once Arc get's updated.
Maybe not in this case, as Agroal does it's action on
Enforcing the sychronization order it's something to take into consideration, but I would like to avoid that complexity. |
Perhaps compare the performance impact of enabling/disabling Hibernate ORM database connection caching. If the connection caching doesn't help performance, then consider disabling the database connection caching instead of forcing the synchronization order. You probably need to check the performance impact with an active JTA transaction and without a JTA transaction as that could impact how the JCA layer does its database connection caching. |
Let me clarify a couple of things:
Many thanks @manovotn for stepping in on the Arc side - that seems like the sensible solution. |
FTR, Arc portion of the fix was merged into main branch. |
Any updates? |
Is this still a problem with the latest versions of Quarkus? |
@geoand yes, this issue still exist when setting the Quarkus version in the reproducer to 2.16.6.Final and then running
|
This is really not good... @mmusgrov Can you help ? |
Are you guys asking us to provide configurable ordering semantics for synchronizations, if so it's been discussed before in the spec group (jakartaee/transactions#65). Or are you wanting to explore adding something specific to the config for the narayana-jta extension? |
WildFly has a layer to deal with ordering - should Quarkus have the same (in some way) ? It is a discussion how to deal with it here - but TX resources needs to be handled correctly; otherwise we have to enforce 2PC semantics. |
I will propose a narayana-jta extension change and base it on WLFY-3619 which adds similar functionality for WildFly by wrapping the TSR. |
I think I figured out what's going on: The reproducer performs a Hibernate update and also registers a CDI This scenario results in three interposed synchronizatons; Hibernate, Agroal and ARC in that order (the CDI beforeCompletion observer is called from the ARC synch). With the observer present, a connection wrapper is opened by the observer to perform a hibernate query, but nothing closes the wrapper, and then the transaction moves to the commit phase and calls LocalXAResource#commit() [1] which detects that there is still an open wrapper [2] and generates the offending WARN(ing) message. Remark: Without the observer all the wrappers have been closed before commit phase runs (and that the Agroal connection is returned to the pool, ie gets closed, during the Agroal afterCompletion synchronization). I did add synchronization ordering semantics to the narayana-jta extension to experiment with ordering the ARC synch to run first (ARC, Hibernate, Agroal) but that turned out to not be possible because Hibernate is by-passing the Quarkus TSR [3] and is registering directly with Narayana [4], @Sanne who should I ask to get that looked into i.e. to decouple hibernate core from narayana? If running the ARC synch first does not fix the issue then where is the best place to ensure that the wrapper (opened by the ARC synch) is closed before the commit phase runs? [1] https://github.com/agroal/agroal/blob/1.11/agroal-narayana/src/main/java/io/agroal/narayana/LocalXAResource.java#L68 |
Hi Mike, thanks for looking! The component you point at in [4] is an SPI - in fact we can register any different strategy implementation. Within Quarkus, this is controlled by https://github.com/quarkusio/quarkus/blob/ebee0a4b66d1b4dba9c51165e78d22fbf3b90d3e/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/customized/QuarkusJtaPlatform.java You're free to customize that class, you can either change its implementation of |
P.S. I hope we can change our implementations to avoid such problems w/o needing to expose configuration properties. In an ideal world we should enforce the safer approach w/o giving any alternatives. |
Thanks, I'll take a look and see how to configure it to use the |
I took another look at this and found that if I order the ARC synchs to run first the WARN message disappears. @Sanne I think the |
Actually if the hibernate-orm change isn't required for this issue it's best if I remove that change. I do have a follow up question: will running the ARC interposed synchs first cause any issues (they run last in the current codebase). |
What impact would an application library registering a sync have on this ordering scheme? Would it help to instead ensure that Hibernate ORM syncs (perhaps both before/after competition) always run last? |
The way I coded it [1] means that such an interposed sync will run after the ARC ones but before the Agroal ones. Apart from that caveat all other interposed syncs will be ordered in the order that they were registered.
The Agroal afterCompletion synchronization [2,3] needs to run last: it checks that all of the connection wrappers are closed and it returns the connection back to the connection pool. But I could run the Hibernate ORM syncs after the other ones, so [ARC, other syncs, Hibernate, Agroal]? (Narayana runs the afterCompletions in reverse order compared to beforeCompletions and we would want to maintain that policy). [1] https://github.com/quarkusio/quarkus/compare/2.0.2.Final...mmusgrov:quarkus:18737-synch-order-on-2.0.2.Final?expand=1#diff-eb042caa54555177c75fa37d6a25c9718840b45ee89997cf60fea2d6e5e15331R85 |
That sounds reasonable 👍 N.B. I'm not an expert in this field myself. |
Thanks for the code link and explanation. The [1] code ordering looks like the best approach. |
Fixed by #34160 |
@yrodiere I'm currently experiencing this issue on the newest version of Quarkus 3.12.0. Despite the issue being marked as closed, it appears to still persist in this latest release. Should I open a new issue to track this, or would it be possible to reopen this one? |
Please open a new issue, thanks |
Describe the bug
When using javax.enterprise.event Events and an Observer with TransactionPhase.BEFORE_COMPLETION that queries anything with sql the WARN log
WARN [io.agr.pool] (executor-thread-0) Datasource '<default>': Closing open connection prior to commit
appears.Expected behavior
No WARN log, as everything works as intended.
Actual behavior
Logs
WARN [io.agr.pool] (executor-thread-0) Datasource '<default>': Closing open connection prior to commit
How to Reproduce?
Open the quarkus hibernate-orm-quickstart project.
@Inject Event<Fruit> eventBus;
in the FruitResourceeventBus.fire(fruit);
in the create methodOutput of
uname -a
orver
Microsoft Windows [Version 10.0.19042.928]
Output of
java -version
java version "11.0.5" 2019-10-15 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.5+10-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.5+10-LTS, mixed mode)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
1.13.6.FINAL and 2.0.2.FINAL
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.6.3
Additional information
No response
The text was updated successfully, but these errors were encountered: