为什么 Hibernate 仅在事务内自动刷新?

发布于 2024-10-21 05:17:40 字数 1335 浏览 0 评论 0原文

这种行为背后的理由是什么?

如果由于某种原因我在事务之外执行两个合适的操作(不推荐,我知道!)并且我已将 Hibernate 配置为自动刷新,那么如果第二个操作我期望它会自动刷新应该触发自动刷新(例如 listiterateexecuteUpdate)。

如果不是对 autoFlushIfRequried 方法的第二行进行显式检查,这正是会发生的情况:

protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
    errorIfClosed();
    if ( ! isTransactionInProgress() ) {
        // do not auto-flush while outside a transaction
        return false;
    }
    AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
    AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
    for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
    autoFlushEventListener[i].onAutoFlush(event);
    }
    return event.isFlushRequired();
}

更新:谢谢 axtavt 用于查找导致此更改的 Hibernate 问题(在 3.2 中):FlushMode.AUTO ->在事务外提交

相关问题仍然悬而未决:在 FlushMode.MANUAL/ 的情况下延迟 IDENTITY 插入/从来没有,但是这两个讨论都没有提供“在事务之外操作时,FlushMode.AUTO 是一件坏事”的理由。

What is the rationale behind this behavior?

If for some reason I execute two suitable operations outside a transaction (not recommended, I know!) and I've configured Hibernate to auto-flush, I would expect it to auto-flush if the second operation is one that should trigger an auto-flush (like list, iterate, or executeUpdate).

That's exactly what would happen, if not for the explicit check on the second line of the autoFlushIfRequried method:

protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
    errorIfClosed();
    if ( ! isTransactionInProgress() ) {
        // do not auto-flush while outside a transaction
        return false;
    }
    AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
    AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
    for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
    autoFlushEventListener[i].onAutoFlush(event);
    }
    return event.isFlushRequired();
}

Update: Thank you axtavt for finding the Hibernate issue that prompted this change (in 3.2): FlushMode.AUTO -> COMMIT when outside a transaction.

A related issue is still open: delay IDENTITY insertions in the case of FlushMode.MANUAL/NEVER, but neither discussion provides the rationale for saying "When operating outside a transaction, FlushMode.AUTO is a bad thing."

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰火雁神 2024-10-28 05:17:40

因为 FlushMode 的文档说

有时会在查询执行之前刷新会话,以确保查询永远不会返回陈旧状态。这是默认的冲洗模式。

所以,auto 并不意味着你所想的那样。可以说,这个名称选择得不好,但这并不意味着每次会话操作后都会进行刷新。因此,它与 JDBC 的自动提交不同,后者在 JDBC 语句之后进行提交。

Because the docummentation for FlushMode says

The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.

So, auto doesn't mean what you think it means. The name is, arguably, badly chosen, but it doesn't mean a flush is made after each session operation. It's thus not similar to JDBC's autocommit, which makes a commit after ever JDBC statement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文