【问题标题】:where we need to set hibernate session to thread local object我们需要将休眠会话设置为线程本地对象
【发布时间】:2013-07-24 21:19:27
【问题描述】:
ThreadLocal<Session> tl = new ThreadLocal<Session>();
    tl.set(session);

获取会话,

  Employee emp = (Employee)((Session)tl.get().get(Employee.class, 1));

如果我们的应用程序是基于 Web 的,则 Web 容器会为每个请求创建一个单独的线程。 如果所有这些请求同时使用同一个 Session 对象,我们应该得到 在我们的数据库操作中出现不需要的结果。 为了克服上述结果,最好将我们的会话设置为 threadLocal 对象 这不允许会话的并发使用。我认为,如果它是正确的应用程序性能应该很差。 在上述情况下有什么好的方法。 如果我走错了路,在哪些情况下我们需要使用 ThreadLocal。 我是hibernate的新手,如果这种类型的提问很愚蠢,请原谅。 提前致谢。

【问题讨论】:

  • ThreadLocal 的核心概念是,“每个通过 get 或 set 方法访问 ThreadLocal 变量的线程都有自己的、独立初始化的变量副本”。
  • 你在使用 spring 和 hibernate 吗?
  • 不要自己这样做。为此使用 Hibernate 本机支持:SessionFactory.getCurrentSession()。看来你的 Hibernate 教程已经过时了。
  • 是的@Santosh 我正在使用 Spring 和休眠
  • is SessionFactory.getCurrentSession() 在多线程环境中产生正确的结果。 @JB 尼泽特

标签: java hibernate


【解决方案1】:

将 Hibernate Session 放入 ThreadLocal 不太可能实现您想要的请求之间的隔离。当然,您使用由DataSource 的连接池实现支持的SessionFactory 为每个请求创建一个新的Session,这意味着对Session 的本地引用无论如何都在堆栈上。更改对成员变量的本地引用只会使代码复杂化,恕我直言。

无论如何,确保单个容器内的隔离并不能解决实际问题 - 如何在多线程环境中保持一致性的同时有效地访问数据。

您提到的问题有两个部分 - 第一个是数据库连接是一种昂贵的资源,第二个是您需要确保线程/请求之间的某种程度的数据一致性。

解决资源问题的一般方法是使用数据库连接池(我猜你已经在这样做了)。在处理每个请求时,会从池中获取连接并在完成后返回,但重要的是池中的连接会在请求的生命周期之后保持,从而避免每次需要时创建连接的成本。

一致性问题有点棘手,没有一种尺寸适合所有model。你需要做的是考虑你需要什么级别的一致性——比如数据是否在写入的同时被读取是否重要,更新是否必须是原子的,等等。

一旦您知道这些问题的答案,您需要在两个地方查看一致性 - 数据库和代码。

对于数据库,您需要查看 database level locks 并通过应用适当的 isolation levels 创建适合您应用程序的方案。

有了代码,事情就有点复杂了。数据通常会在更新被写回之前加载并显示一段时间 - 如果有单个用户则没有问题,但在多用户系统中,可能会根据陈旧数据进行更新或同时发生多个更新。拥有最后一次更新获胜的策略可能是可以接受的,在这种情况下它很简单,但如果没有,您将需要使用版本号或旧/新比较来确保应用更新时的完整性。

【讨论】:

    【解决方案2】:

    我不确定你是否有使用ThreadLocal 的冲动。使用ThreadLocal 来存储会话对象绝对不是一个好主意,特别是当您使用hibernate 和spring 时。

    在 Spring 中使用 Hibernate 的典型方案是:

    1. 在您的 DAO 中注入 sessionFactory。我假设您已经配置了 sessionFactory,它由 池化数据源 支持。

    2. 现在在您的 DAO 类中,可以按如下方式访问会话。

      Session session = sessionFactory.getCurrentSession();

    这是related article 的链接。

    请注意,此示例特定于 Hiberante 3.x API。这在内部处理了会话创建/关闭/线程安全方面,并且也很整洁。

    【讨论】:

      猜你喜欢
      • 2012-06-29
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 2011-02-13
      • 2014-01-01
      • 1970-01-01
      相关资源
      最近更新 更多