简体   繁体   English

Java Hibernate会话及其范围?

[英]Java Hibernate session and its scope?

I have just started using Hibernate with HSQLDB. 我刚刚开始将Hibernate与HSQLDB结合使用。 In the tutorial they tell me not to use the anti-pattern "session-per-operation". 在教程中,他们告诉我不要使用反模式“每次操作会话”。 However, each time I commit a transaction the session is closed as well. 但是,每次提交事务时,会话也会关闭。 How am I supposed to avoid using getCurrentSession() if commit() closes the session? 如果commit()关闭会话,我应该如何避免使用getCurrentSession()

I'm a bit curious on how people usually hande the scope of the session. 我对人们通常如何处理会议范围感到好奇。 I have seen several samples on building web applicatons where you have one session per request. 我在构建Web应用程序时看到了几个示例,其中每个请求一个会话。 In my case I'm building a service, and cannot apply the same idea. 就我而言,我正在构建服务,因此无法应用相同的想法。 The service is running 24/7, and sporadically it does some database operations. 该服务运行24/7,偶尔会执行一些数据库操作。 Should I keep the database session alive all the time, and just use transactions as boundaries between operations (considering a case where my transaction commits do not close the session) or should I just create a new one for each operation (which is the anti-pattern, but how else?). 我应该始终保持数据库会话是活动的,只使用事务作为操作之间的边界(考虑我的事务提交不关闭会话的情况)或者我应该为每个操作创建一个新的(这是反...模式,但如何?)。

Thanks in advance! 提前致谢!

That behaviour is determined by the implementation of CurrentSessionContext in use. 该行为由正在使用的CurrentSessionContext的实现决定。 The default happens to be ThreadLocalSessionContext which does close-on-commit, but you're by no means constrained to that. 默认碰巧是ThreadLocalSessionContext ,它会在提交时关闭,但是您绝不会受限于此。

You can configure/build any type of session scope you like by using ManagedSessionContext and binding/unbinding sessions at the appropriate beginning and end of life cycle. 您可以通过在适当的生命周期的开始和结束时使用ManagedSessionContext并绑定/取消绑定会话来配置/构建所需的任何类型的会话范围。 It seems to make sense for you that you would bind a Session at the entry to your service's unit of work and unbind it at the exit. 您似乎有意义的是,您将条目中的会话绑定到服务的工作单元,并在出口处解除绑定。 (It is of course no trivial task to build robust code for doing this. Particularly remember that you're expected to make a new Session if an exception comes out of one of its methods.) (为此,构建健壮的代码当然不是一件容易的事。尤其要记住,如果从其中一种方法中产生异常,则应该进行新的Session 。)


Responding to comment was getting too large for a comment. 对评论的回应太大了,无法发表评论。

That is the default behaviour because it's the only thing that's "safe" without additional work or configuration provided by the user. 这是默认行为,因为这是唯一“安全”的事情,无需用户提供额外的工作或配置。 The "commit" is the only lifecycle point that Hibernate is able to "see" if you don't help it out, so it has to close there or risk the session being left dangling forever. 如果您不帮忙,那么“提交”是Hibernate能够“看到”的唯一生命周期点,因此它必须在此关闭,否则可能会导致会话永远悬而未决。

Determining potential session life cycle boundaries requires a fair bit of knowledge about what you're actually doing. 确定潜在的会话生命周期边界需要对您实际执行的操作有相当多的了解。 "It's a background service" isn't much to go on. “这是一项后台服务”没什么可继续的。 Assuming it does something like sit idling and wake up every X minutes, do some work, then go back to sleep for another X minutes, then that would be a good boundary to open then close a session. 假设它像闲坐一样每隔X分钟醒来,做一些工作,然后再入睡X分钟,那么打开然后关闭会话将是一个很好的界限。

You may be using an over-broad definition of 'operation' when talking about 'session per operation' being an anti-pattern. 当谈论“每次操作的会话”是一种反模式时,您可能会使用“操作”的广泛定义。

They mean don't do something like (fictitious requirements for your service): 他们的意思是不要做(像你的服务的虚构要求):

  1. Wake Up Service 叫醒服务
  2. Open Session 公开会议
  3. Read File location from database 从数据库中读取文件位置
  4. Close Session 关闭会话
  5. Open file 打开文件
  6. Open Session 公开会议
  7. Update Database tables from current file state 从当前文件状态更新数据库表
  8. Close Session 关闭会话
  9. Open Session 公开会议
  10. Write Activity Log to Database 将活动日志写入数据库
  11. Close Session 关闭会话
  12. Sleep Service 睡眠服务

It would be perfectly reasonable to do that in one session then close it at the end. 在一个会话中执行此操作然后在结束时关闭它是完全合理的。 In a single threaded environment where you're managing everything yourself within known boundaries, you can really just open and close the session yourself without using currentSession if you want. 在单线程环境中,您可以在已知边界内自行管理所有内容,您可以自己打开和关闭会话,而无需使用currentSession You just need to make sure it gets closed in the event of an exception. 您只需要确保在发生异常时关闭它。 If you're listening for an operating system event, the event handling would be a perfectly fine scope for the session. 如果您正在侦听操作系统事件,则事件处理将是会话的理想范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM