Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate ThreadLocal Session management compatible with ForkJoinPool?

I usually use the Hibernate ThreadLocal session management pattern in Java web projects:

The Thread Local Session pattern makes use of the java.lang.ThreadLocal class to create a Session that is accessible from a single application thread. This is particularly convenient in multithreaded applications, such as web applications.

In projects I implement this with

<property name="current_session_context_class">thread</property>

in the hibernate.xml and using SessionFactory.getCurrentSession() to get a session whenever I need one.

Now I have a program that is not a Servlet, but does heavy parallel computing and database interaction.

I want to implement this with a ForkJoinPool. Now I wonder whether it is a mistake to use Hibernate ThreadLocal session management in this scenario. As far as I understand, a ForkJoinPool uses a smaller number of threads and shares them among running tasks while other tasks are sleeping. (Motivated by stalling/annoying " task in transaction' connections,) I want to close() every Hibernate Session after a unit of work.

So.. when I call HibernateSessionFactory.getThreadLocalSession().close() at the end of my Task - and the Task is run in a ForkJoinPool - will troubles arise? Should I drop the ThreadLocal pattern for heavy parallel calculations and manage the Sessions myself?

Thanks in advance for any answers.

like image 589
alfonx Avatar asked Apr 03 '12 07:04

alfonx


People also ask

Can Hibernate Session be shared between threads?

If you were sharing a Hibernate Session between two threads, then one thread changes might not be visible to some other thread (without proper synchronization or volatile reads).

Is Session factory thread safe in hibernate?

The SessionFactory is a thread safe object and used by all the threads of an application. The SessionFactory is a heavyweight object; it is usually created during application start up and kept for later use. You would need one SessionFactory object per database using a separate configuration file.

What is Session management in hibernate?

A Session is used to get a physical connection with a database. The Session object is lightweight and designed to be instantiated each time an interaction is needed with the database. Persistent objects are saved and retrieved through a Session object.

What is Session in hibernate with example?

The Session interface is the main tool used to communicate with Hibernate. It provides an API enabling us to create, read, update, and delete persistent objects. The session has a simple lifecycle. We open it, perform some operations, and then close it.


1 Answers

Using ThreadLocalSessionContext could be problematic for you, but it depends on what your tasks are doing.

A ForkJoinPool (javadocs) is meant for use in cases where tasks spawn other tasks (the fork), and wait for them to complete (the join). While waiting, the Thread that was executing the parent task may be re-used to execute a child task. According to the javadocs for ThreadLocalSessionContext, the Session gets closed when you commit a transaction you get from it (ie there's only ever one transaction per Session).

So, if you have a 'parent' task that calls sessionFactory.getCurrentSession(), and does some stuff, then calls commit(), the Session gets closed and there's no danger of inappropriate interaction.

However, if you spawn children tasks AFTER calling .getCurrentSession() and BEFORE calling .commit(), you may run in to issues because other tasks may execute on this Thread, and .getCurrentSession() would return the session used by the parent task. This is almost certainly not what you want, because the children tasks should presumably be doing the same thing as each other, and you wouldn't want one arbitrarily sharing Session state with the parent while others don't.

So in summary, you should:

  • Not call session.close() if you get the Session from .getCurrentSession(), because it's the responsibility of the CurrentSessionContext to deal with that.
  • Be in a committed relationship before having children.... I mean, call .commit() before spawning children tasks.

As a footnote, I found this wiki page to be a helpful read on the subject as well.

like image 112
sharakan Avatar answered Nov 15 '22 02:11

sharakan