Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在JSF web应用程序中使用惰性加载时的Hibernate会话处理_Multithreading_Hibernate_Jsf_Session_Lazy Loading - Fatal编程技术网

Multithreading 在JSF web应用程序中使用惰性加载时的Hibernate会话处理

Multithreading 在JSF web应用程序中使用惰性加载时的Hibernate会话处理,multithreading,hibernate,jsf,session,lazy-loading,Multithreading,Hibernate,Jsf,Session,Lazy Loading,各国: 会话的实例是轻量级的,并且创建和销毁成本较低。这一点很重要,因为您的应用程序需要始终创建和销毁会话,可能是在每次请求时。Hibernate会话不是线程安全的,按照设计,一次只能由一个线程使用 因为Tomcat在多个线程中处理HTTP请求,所以在web应用程序中线程安全是非常必要的。因此,我读到: 会话应该是每个方法的局部变量。通过这样做,DAO将成为无状态的,因此本质上是线程安全的,不需要任何同步 让我们以这种方式在基于JSF的web应用程序中实现它: private static fi

各国:

会话
的实例是轻量级的,并且创建和销毁成本较低。这一点很重要,因为您的应用程序需要始终创建和销毁会话,可能是在每次请求时。Hibernate会话不是线程安全的,按照设计,一次只能由一个线程使用

因为Tomcat在多个线程中处理HTTP请求,所以在web应用程序中线程安全是非常必要的。因此,我读到:

会话应该是每个方法的局部变量。通过这样做,DAO将成为无状态的,因此本质上是线程安全的,不需要任何同步

让我们以这种方式在基于JSF的web应用程序中实现它:

private static final SessionFactory sessionFactory;

public Object read(Class c, Integer id){
    try{
        Session session = sessionFactory.openSession();
        return session.get(c, id);
    }finally{
        session.close();
    }
}
当谈到延迟加载时,您肯定会遇到LazyInitializationException,在几分钟或几小时后,一些用户交互需要访问存储在用户会话中的对象上的延迟加载集合,该对象是使用上述代码从Hibernate读取的,因为用于加载该集合的会话很久以前就关闭了。(我不认为懒惰加载,这是最常见的,作为一个解决方案。) 继续阅读,我还发现:

您可以由所有DAO使用同一个会话,在初始化期间打开,在关闭时关闭。请注意,其中提到“每个操作的会话数”是一种反模式:

“不要使用每操作会话反模式:不要在单个线程中为每个简单的数据库调用打开和关闭会话。”

在我看来,这与上面提到的方向有些矛盾。我必须保持会话打开并重新使用它,或者我不这样做?我假设,对于任何操作,只要在会话上打开会话而从不关闭它们,就意味着实现了内存泄漏。在这里,使用应用程序范围的会话池也可能不够,因为一个线程可以签出一个会话,而另一个线程可能访问绑定到该会话的延迟加载集合,这就是并发性问题


,但如果没有它,并且给出了一个长期运行、基于JSF、多线程和多用户的web应用程序:如何更好地管理它?

好吧,简单的答案是“这取决于…”

如果你的webapp流量大,用户数量多,我会对每个请求使用一个hibernate会话

如果很少有用户使用长而复杂的会话,我会将一个hibernate会话映射到每个http会话

对于第二种解决方案,您显然忘记了LazyLoading异常,但是您也保持db会话打开,并且通常不是非常活跃

对于第一个,从理论上讲,您更愿意吸收高流量,但您必须在使用对象之前使用session.refresh将对象“重新连接”到数据库

在一些应用程序中,我两者都做。绝大多数用户都有一个请求范围的db会话,他们使用的屏幕也相应地编码。我为超级用户使用会话范围的db会话,通常使用特定的屏幕