Hibernate ThreadLocal会话管理与ForkJoinPool兼容吗?

我通常在Java Web项目中使用Hibernate ThreadLocal会话管理模式:

线程本地会话模式利用java.lang.ThreadLocal类来创建可从单个应用程序线程访问的会话。 这在多线程应用程序(如Web应用程序)中特别方便。

在我实施这个项目

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

hibernate.xml使用SessionFactory.getCurrentSession()来获取会话。

现在我有一个不是 Servlet的程序,但是执行了大量的并行计算和数据库交互。

我想用ForkJoinPool来实现它。 现在我想知道在这种情况下使用Hibernate ThreadLocal会话管理是否是一个错误。 据我所知,ForkJoinPool使用较少数量的线程,并在正在运行的任务中共享它们,而其他任务正在休眠。 (由于拖延/恼人的“事务中的任务”连接),我想在一个工作单元后关闭()每个Hibernate Session。

所以..当我在任务结束时调用HibernateSessionFactory.getThreadLocalSession()。close()并且该任务在ForkJoinPool中运行时会出现问题吗? 我是否应该放弃ThreadLocal模式进行繁重的并行计算并自己管理Sessions?

预先感谢任何答案。


使用ThreadLocalSessionContext对你来说可能会有问题,但这取决于你的任务在做什么。

ForkJoinPool (javadocs)适用于任务产生其他任务(fork)的情况,并等待它们完成(join)。 在等待时,执行父任务的线程可能会被重新用于执行子任务。 根据ThreadLocalSessionContext的javadocs,当你提交一个你从中得到的事务时, Session会被关闭(即每个Session只有一个事务)。

因此,如果您有一个调用sessionFactory.getCurrentSession()的“父”任务并执行某些操作,然后调用commit(),则会话将被关闭,并且不存在不适当的交互风险。

但是,如果在调用.getCurrentSession()并且在调用.commit()之前产生子任务,则可能会遇到问题,因为其他任务可能会在此线程上执行,而.getCurrentSession()将返回父任务使用的会话。 这几乎肯定不是你想要的,因为孩子们的任务应该彼此相同,你不希望任何人与父母任意分享Session状态,而其他人不会。

所以总之,你应该:

  • 如果从.getCurrentSession()获得Session ,则不要调用session.close() ,因为CurrentSessionContext负责处理该事务。
  • 在有孩子之前保持一种忠诚的关系....我的意思是,在产卵儿童任务之前调用.commit()
  • 作为一个脚注,我发现这个wiki页面也是一个有用的阅读主题。

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

    上一篇: Hibernate ThreadLocal Session management compatible with ForkJoinPool?

    下一篇: How can I prevent R from loading a package?