Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple transactions in a single hibernate session (with Spring)

Is it possible to model the following using Hibernate + Spring.

  • Open session
  • Begin transaction
  • Do some work
  • Commit
  • Begin transaction
  • More work
  • Commit
  • Close session

I use the Spring TransactionTemplate which does both session + transaction lifetime scoping.

The reason is that sometimes I have a few stages in a business process and I would like to commit after each stage completes. However I would like to continue using the same persistent objects. If I have a separate session per transaction then I get transient/detached exceptions because the original session was closed.

Is this possible?

like image 932
Mike Q Avatar asked Nov 23 '12 14:11

Mike Q


2 Answers

Yes, Hibernate's Sessions can begin and commit several transactions. What you need to do is to store open session somewhere, then reuse it. Note, that Session is not a thread-safe object, but if you're sure it won't have problems with concurrency, what you need is just to use TransactionSynchronizationUtils to bind a session to the thread resources and then unbind it when desired, you can find an example here or you can take a look at OSIV and its standard implementations.

This is a very complicated thing, it's much easier and thus desirable that you close your session right away and don't reuse it, because it may bring troubles:

  • The objects inside of cache are not automatically evicted, thus your Session will grow in size until OutOfMemory.
  • The objects inside of session are not flushed unless they are dirty, thus the chance that object was changed by another user is larger and larger. Ensure that only a single user is going to change writable objects.
  • If some exception happens during one of steps, you have to ensure you close the session. After exception occurred inside of Session, this object is not reusable.
  • If transaction was rolled back, the session is cleared by Spring, thus all your objects become detached. Make sure your discard everything if at least one of transactions was rolled back.
like image 200
Stanislav Bashkyrtsev Avatar answered Oct 02 '22 22:10

Stanislav Bashkyrtsev


You could achieve this using the OpenSessionInView pattern. Spring provides a javax.servlet.Filter implementation which you could use if you're working in a servlet environment (question doesn't say so). This will ensure that your Hibernate session is kept open for the duration of the request rather than just for an individual transaction.

The Javadoc on this class is pretty comprehensive and might be a good starting point.

like image 25
Alex Barnes Avatar answered Oct 02 '22 22:10

Alex Barnes