代码之家  ›  专栏  ›  技术社区  ›  Andrei Herford

原则:如何防止事务通过捕获的异常变成“仅回滚”?

  •  0
  • Andrei Herford  · 技术社区  · 7 年前

    postRemove 事件处理程序。即使捕获到异常,删除也会失败,因为无法再提交事务。

    完整的故事:

    我需要在一个数据库中跟踪一些已删除的实体 Symfony 3.4 基于web服务的web应用 Doctrine .

    为此,我创建了一个 EventSubscriber 移除后 事件以检查是否需要记录已删除的实体。在这种情况下,实体UUID存储在 DeleteLog th DB表。

    这种方法效果很好,但在极少数情况下会持续使用 DeleteLogEntry 失败,因为给定UUID已经存在需要唯一的日志项。

    这个问题的根源是一些我无法改变自己的第三方代码。作为一种临时解决办法,他试图抓住这个机会 UniqueConstraintViolationException . 这并不能解决问题,因为我现在得到 ConnectionException

    事务提交失败,因为该事务已标记为 仅回滚。

    有可能解决这一困境吗?

    删除日志条目 在创建新UUID之前,已存在给定UUID。但由于这一问题只在极少数情况下发生,因此大多数情况下检查结果都是否定的。当然,无论如何运行检查都不会对性能造成灾难性影响,但似乎并不是最好的解决方案。

    是否有可能捕获异常并防止事务被标记为仅回滚?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Andreas    7 年前

    不,不可能不标记事务。

    nested transaction 对于 postRemove 如果失败,则不应提交其他事务。在这种情况下,将事务标记为仅回滚(甚至关闭实体管理器)是预期的行为,因为条令没有其他方法来确保一致性,因为不支持真正的嵌套事务。

    如果性能不是问题,则检查 DeleteLogEntry 这是一个很好的选择。

    其他可能的解决办法:

    • 删除日志条目
    • 使用单独的实体管理器/连接进行更新