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.


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.

    链接地址: http://www.djcxy.com/p/58650.html

    上一篇: Android自定义EditText不在ICS中显示光标

    下一篇: Hibernate ThreadLocal会话管理与ForkJoinPool兼容吗?