Skip to content
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

Guice persist JpaLocalTxnInterceptor gets stuck when connection to database drops during transaction #1179

Open
bgooren opened this issue Apr 21, 2018 · 6 comments

Comments

@bgooren
Copy link

bgooren commented Apr 21, 2018

We have an interesting case in some production code: inside a method annotated with transactional some operation takes much longer than expected, and our database connection pool closes the database connection.
A query inside the method then throws an exception ("Connection has already been closed").

The JpaLocalTxnInterceptor takes care of starting a unit of work (we don't manage it ourselves in this instance). I would expect the unit of work to have ended after the method call.

However, this is what happens:

  • rollbackIfNecessary is called, which tries to execute a transaction rollback
  • the rollback throws an exception ("Connection has already been closed")
  • as the transaction is still seen as active, the unit of work is not closed (line 82 in JpaLocalTxnInterceptor)
  • every next call to the annotated method tries to reuse the unit of work and fails

The above can be circumvented by managing the unit of work ourselves. But that means that we cannot rely on the "it just works"-behavior of the transactional annotation, which is a shame.
It also means more boilerplate code in every location where we now rely on the transactional annotation to do the work for us.

Ideally the interceptor should end the unit of work, even when it cannot perform a rollback.

@Vogel612
Copy link
Contributor

#1136 seems somewhat related. The fix itself is similar

@bgooren
Copy link
Author

bgooren commented Apr 22, 2018

Somewhat, yes. In my case neither a commit() or rollback() will work, as the underlying connection was closed. This is not handled by JpaLocalTxnInterceptor, which means it gets stuck reusing a broken connection. In your case you want to prevent a call to commit() after your own call to rollback(), to prevent an exception from being thrown.

@cs-devil
Copy link

cs-devil commented Sep 6, 2018

@bgooren have you find any way to solve this issue.

@Vogel612
Copy link
Contributor

Vogel612 commented Sep 6, 2018

@cs-devil there is an open PR from yours truly to fix the issue, which has been languishing for a while awaiting a restart of an intermittently failing CI here

@jberrend
Copy link

Is there any fix for this that is planned to be merged? We have run into the exact same problem with connection closed errors which makes it impossible to use Guice's @Transactional annotation since dead EntityManger's get locked into our threads.

To get around this, we built our own method interceptor which manages the UnitOfWork lifecycle in a more appropriate way for our use-case.

@bgooren
Copy link
Author

bgooren commented Mar 19, 2021

@qwertee not that I'm aware of.

We already built a custom guice-persist implementation due to another issue, so it was a small step to add a custom interceptor for this. So that works for us. I'm not holding my breath while we wait for the maintainers to fix this (seeing that many pull requests are never merged or closed) :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants