【问题标题】:How to close & open a new Hibernate Session in case of Exception出现异常时如何关闭和打开新的 Hibernate 会话
【发布时间】:2018-09-27 10:16:06
【问题描述】:

上下文/设置

我们在带有 Spring 和 Hibernate 集成的应用程序中使用 open-session-in-conversation-filter 模式。

我们正在使用 Springs 声明式事务管理,使用 org.springframework.transaction.interceptor.TransactionProxyFactoryBean

当应用程序收到请求时,我们会执行多个数据库活动(插入/更新),其中更新和插入单独刷新到数据库并提交事务。

问题

假设对于其中一个插入/更新,引发了数据库异常,休眠会话按预期关闭,因为会话处于无效状态。

即使在此之后,如果我不想返回请求并想继续我的请求并完成我无法完成的其他活动,因为会话已关闭并且通过此会话的任何后续调用都失败了,原因很明显。

我在编写解决方案时需要帮助,我可以关闭现有会话并打开一个新会话,并使用 TransactionSynchronizationManager 将最新会话附加到线程,但不知道如何执行此操作,因为我可能需要很多地方要在流程中执行此操作,是否有通用的方法来执行此操作?它甚至是正确的设计吗?

即使我实现了这一点,与前一个会话分离的实体如何才能自动附加到新会话,以便代理无缝工作?

【问题讨论】:

    标签: java hibernate spring-mvc spring-transactions open-session-in-view


    【解决方案1】:

    我们正在使用 open-session-in-conversation-filter 模式 具有 Spring 和 Hibernate 集成的应用程序。

    对话模式就像 Java EE 中的扩展持久性上下文一样工作,就像您在此处描述的那样。如果遇到异常,则必须丢弃所有内容并从头开始。

    现在,如果您想要更大的灵活性,您可以只使用分离实体并在每个请求中使用新的Session,这将合并分离的实体。

    但是,如果实体状态总是会导致异常怎么办?您如何确定实体并简单地忽略它?如果它链接到其他实体怎么办。

    因此,这个问题没有简单的解决方案。你可以做的是:

    1. 使用您从数据库中读取的初始实体捕获初始状态并将其存储在HttpSession、Redis 等中。
    2. 存储用户提交的信息,因此如果出现异常,您可以使用与错误消息相同的更改重新呈现 UI。

    这样,用户不会丢失他们所做的更改,并且可以根据错误消息在应用更正后重试。

    【讨论】:

    • 感谢弗拉德的快速回复。我指的是一个不同的问题,即使我的一个更新失败并继续其他活动,我也想继续执行相同的请求,但为此我需要创建一个新会话并将所有实体附加到它.这是否需要手动完成,因为我可能无法跟踪旧会话的所有实体?是否有一个通用的地方/模板类,我可以在其中创建此会话,以便我的任何事务失败我应该创建一个新会话?
    • 是的,您必须手动执行此操作。这就是为什么你最好按照我的建议去做。
    猜你喜欢
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2015-01-03
    • 2014-02-18
    • 2014-11-27
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    相关资源
    最近更新 更多