【问题标题】:How can I configure Hibernate to immediately apply all saves, updates, and deletes?如何配置 Hibernate 以立即应用所有保存、更新和删除?
【发布时间】:2010-10-15 14:50:17
【问题描述】:

如何配置Hibernate 以在会话执行每个操作后立即将所有保存、更新和删除应用到数据库服务器?默认情况下,Hibernate 将所有保存、更新和删除操作排入队列,并仅在 flush() 操作、提交事务或发生这些操作的会话关闭之后将它们提交到数据库服务器。

立即刷新数据库“写入”操作的一个好处是程序可以在发生它们的代码块中捕获和处理任何数据库异常(例如ConstraintViolationException)。对于延迟刷新或自动刷新,这些异常可能在导致 SQL 操作的相应 Hibernate 操作之后很长时间发生。

更新:

根据接口Session的Hibernate API文档,在会话结束之前捕获和处理数据库异常的好处可能根本没有好处:“如果会话抛出异常,则必须回滚事务并且会话被丢弃。异常发生后,Session的内部状态可能与数据库不一致。"

也许,使用 try-catch 块包围“立即”Hibernate 会话写入操作的好处是在异常发生时立即捕获并记录异常。立即刷新这些操作是否还有其他好处?

【问题讨论】:

    标签: java database hibernate


    【解决方案1】:

    如何配置 Hibernate 以在会话执行每个操作后立即将所有保存、更新和删除应用到数据库服务器?

    据我所知,Hibernate 没有为此提供任何便利。但是,它看起来像 Spring 一样,您可以通过将它们的 HibernateTemplateHibernateInterceptor 分别转换为该刷新模式来进行一些数据访问操作 FLUSH_EAGER (source)。

    但我强烈建议您仔细阅读javadoc(我会回来讨论)。

    默认情况下,Hibernate 将所有保存、更新和删除操作排入队列,并仅在 flush() 操作、提交事务或发生这些操作的会话关闭之后将它们提交到数据库服务器。

    关闭会话不会刷新。

    立即刷新数据库“写入”操作的一个好处是程序可以在发生它们的代码块中捕获和处理任何数据库异常(例如 ConstraintViolationException)。对于延迟或自动刷新,这些异常可能在导致 SQL 操作的相应 Hibernate 操作之后很久才发生

    首先,DBMS 在插入(或更新)或后续提交(这称为立即或延迟约束)时会再次出现约束违规。所以没有保证,您的 DBA 甚至可能不想要立即约束(尽管这应该是默认行为)。

    其次,我个人认为立即冲洗的弊端多于好处,正如 FLUSH_EAGER 的 javadoc 中的黑底白字所解释的那样:

    急切的冲洗会导致立即 与数据库同步, 即使在交易中。这引起 不一致的出现和抛出 立即出现相应的异常,并且 参与的 JDBC 访问代码 同一笔交易将看到 更改,因为数据库已经 那时就知道他们了。但是缺点 是:

    • 与数据库的额外通信往返,而不是单次 事务提交时批处理;
    • 如果 Hibernate 需要实际的数据库回滚这一事实 事务回滚(由于已经 提交的 SQL 语句)。

    相信我,增加数据库往返次数和丢失批处理语句会导致性能严重下降

    另外请记住,一旦遇到异常,除了丢弃会话之外,您无能为力。

    总而言之,我很高兴 Hibernate 将各种操作排入队列,我当然不会将此 EAGER_FLUSH flushMode 用作一般设置(但可能仅用于实际需要 Eager 的特定操作,如果有的话)。

    【讨论】:

    • 所以关闭 Hibernate 会话会有效地丢弃所有挂起的更新操作?
    • Hibernate 是否还会在刷新时将更新操作聚合到单个更新中?
    • @Derek 关闭会话(应该在事务之外完成)不会刷新。所以是的,更改被丢弃。是的,在刷新之前会在内存中进行更改。
    【解决方案2】:

    查看autocommit 虽然不推荐。如果您的工作包括多个更新或插入 SQL 语句,您自动提交了一些工作,然后语句失败,您有一个潜在的艰巨任务,即撤消操作的第一部分。当“撤消”操作失败时,它会变得非常有趣。

    不管怎样,here's a link that shows how to do it

    【讨论】:

    • 我不想自动提交事务,我只想在 Hibernate 会话操作发生后立即将它们刷新到数据库,但仍然在 Hibernate 关闭时提交的事务的上下文中会议。 Hibernate 可以在每次写入操作发生时“自动刷新”吗?
    • 谷歌搜索休眠和自动刷新会出现很多点击。当然,这可能不是您想要的。但是为每个写入的 DAO 方法添加一个 flush() 并不难。
    • 这不能回答问题,自动提交和“急切”是两个不同的东西。
    • 是的,但我最初并不清楚 OP 的要求。
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 2012-09-11
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多