【问题标题】:Rollback Spring Transaction after network failure网络故障后回滚 Spring Transaction
【发布时间】:2018-11-13 15:06:05
【问题描述】:

我正在开发基于 SpringBoot 的相当简单的 RESTful 服务。我正在使用 Ebean 和 SpringData。我所有的 REST 方法都用 @Transactional 注释:

@Transactional
@PostMapping
public Entity createEntity(...) {
   // some code
}

我面临的问题是,如果存在网络问题但此方法无异常执行,事务仍将被提交。例如,客户端可能会发送数据,我的代码会创建记录,但服务器无法将响应发送回客户端。在这种情况下,我希望事务回滚,但我没有找到这样做的方法。

在这种情况下甚至可以回滚事务吗?也许我忽略了一个 Spring 平台限制。

谢谢

编辑:回答下面的答复并进一步说明问题:回滚事务很容易。棘手的部分是运行任何代码以响应网络故障。我希望我可以配置 Spring 来为我做这件事。就像“等到你发送了最后一个字节,然后回滚或提交事务”。我当前的代码将在 createEntity() 方法完成后立即提交事务。

【问题讨论】:

  • 你是怎么解决这个问题的?
  • @humbleCoder 我没有。现在想想,我觉得根本不值得解决。即使您发送数据,客户端也可能无法读取它(即在解析响应期间崩溃)。因此,您只需要接受这样一个事实,即即使您的事务已提交,客户端也可能不知道。
  • 这可能是一个值得解决的严重问题。考虑一个场景,客户端发送了一个 HTTP POST 请求,该请求在服务器数据库中创建了一个实体。服务器创建实体并发回其 ID。但是,客户端在解析来自服务器的响应的过程中崩溃了。后来,当客户端开始运行时,它无法知道这样的实体是否是由服务器创建的以及引用它的方式,因为它无法捕获 ID。客户应该怎么做?它是否应该再次发送 POST 请求,从而可能创建一个类似的实体?

标签: java spring spring-transactions


【解决方案1】:

这不是 Spring 框架的限制。一旦方法成功执行,回滚它不是 spring 框架的@Transactional 责任。

您能做的最好的事情就是拥有一个 ExceptionHandler。请参阅此答案以获得更好的视角:https://stackoverflow.com/a/45034574/945214

您可以做的另一件事是提高整个 HTTP 请求拓扑的性能,从而降低此类潜在故障的可能性(随着触摸时间的减少)。请参阅我关于应用性能的文章:https://www.linkedin.com/pulse/improving-website-performance-kshitiz-garg/

【讨论】:

    【解决方案2】:

    如果您可以找出何时需要回滚(检查返回状态/...),您可以抛出自己的异常。

    注意,因为它只回滚未经检查的异常(否则,如果您希望它回滚任何异常,则需要在 @Transactional 上添加 rollbackFor=Exception.class)。

    见:

    https://www.catalysts.cc/wissenswertes/spring-transactional-rollback-on-checked-exceptions/

    Annotation @Transactional. How to rollback?

    【讨论】:

      【解决方案3】:

      您可以使用以下方法回滚事务而不引发异常:

      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-27
        • 1970-01-01
        • 2018-02-20
        相关资源
        最近更新 更多