【问题标题】:How to add depth to spring's transaction manager如何为 Spring 的事务管理器增加深度
【发布时间】:2012-10-12 13:19:27
【问题描述】:

春季 2.5,休眠。

我们的应用程序架构为具有服务层和管理器层。服务层提供所有只读服务并将结果传达给 UI。对于需要更改数据库的服务,服务层执行所有初始只读功能,然后调用管理器层。

我们围绕我们的管理层设置了一个事务建议,以捕获来自管理层的所有异常并回滚这些事务。这在大多数情况下都非常有效。

问题在于我们让一位经理调用另一位经理来执行某些功能的情况。此功能会引发异常,这是从 UI 调用时真正的异常,但在客户端管理器内部处理并返回成功结果。事务管理器看到抛出了异常并回滚事务,即使异常已成功处理。

这是导致我们悲伤的交易属性。

<tx:method name="*" propagation="REQUIRED" rollback-for="Throwable" no-rollback-for="OverridableException"/>

有没有办法可以指定深度?我想说的是,只回滚最高管理者层调用中的异常,而不是对同一事务的后续调用中的异常。

谢谢!

【问题讨论】:

    标签: java spring hibernate aop


    【解决方案1】:

    通常您希望将对服务层的调用封装在事务建议中,这样如果您的一个服务类对不同的管理器进行多次调用,所有这些都封装在一个事务中 - 如果您正在进行更改,所有他们一起成功或回滚。这通常称为(以及其他名称)Unit of Work pattern

    所以我的建议是重新考虑您在哪里应用您的交易定义。但如果这不可行,您可能希望将事务建议更改为propagation=REQUIRES_NEW,以便每个管理器调用启动一个新事务 - 因此当一个管理器类调用另一个管理器类时回滚内部事务不会回滚整个事务。

    【讨论】:

    • 问题是这不能解决问题。我仍然希望我的经理调用另一个经理来隐藏它的关系并封装功能。第二次调用仍会产生回滚。感谢 REQUIRES_NEW。我需要与我们的团队讨论这个问题,并确保它适合。我担心创建一个独立的交易。
    • 我可能对您需要解决的根本问题感到困惑,尽管嵌套管理器调用引发的异常。这个例外会离开外部经理吗?是外层管理者还是内层管理者?
    • 内层管理者抛出,外层管理者捕捉处理。
    【解决方案2】:

    我最终重构了内部服务方法,将引发异常的部分提取到另一个方法中。然后我调用该方法从外部服务中预先批准我正在执行的操作,并从内部服务中调用新方法以引发异常。这样,我就绕过了抛出的异常。

    希望有一种更好的方法,而无需更频繁地提交。:(

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      相关资源
      最近更新 更多