【问题标题】:Business logic wrapped inside a db transaction包装在数据库事务中的业务逻辑
【发布时间】:2019-08-19 08:21:38
【问题描述】:

在我的应用程序中,我有一个定义路由的 api 层、用于执行业务逻辑的服务层和一个查询数据库的存储库层。服务将调用存储库层以检索数据,执行各种业务逻辑,然后将响应返回给 api 层。

现在,我有一些需要在数据库事务中完成的业务逻辑。例如,假设我的应用允许您购买给定活动的门票:

  1. 服务层调用存储库以通过递减可用票证的数量在数据库中自动保留票证。

  2. 然后服务层发出一个api请求来处理票的支付。

  3. 如果支付成功,服务层调用存储库为用户和给定事件创建一个“订单”。

但是,如果付款失败,我想回滚对门票可用性所做的更改。 (或者如果由于某种原因为用户创建订单失败,同样的事情)。

问题在于,如果服务层知道数据库事务,这似乎是一个泄漏的抽象。有没有更好的范例?

【问题讨论】:

    标签: database design-patterns transactions


    【解决方案1】:

    无论如何,您不希望在发出 API 请求的整个过程中保持数据库事务处于打开状态...您可能想要插入“待处理”订单,然后在收到付款后将状态更改为“已确认” '。这使您可以存储有关错误的详细信息并报告失败的付款

    【讨论】:

    • 是的,这是另一个有效的担忧。但是,我发现您提出的解决方案存在一些问题: 1. 如果付款失败,我们如何将门票添加回来?如果服务器在预订门票,发送支付请求后由于某种原因崩溃,失败,然后崩溃,则会出现此问题。 2. 如果我们有一个待处理的订单来缓解问题 1,则可能存在竞争条件,当订单被确认时,门票不再可用,我们向用户收费
    • 在调用支付 API 之前保留票证 - 这与持有交易没有什么不同,因为在此期间其他进程无论如何都无法使用它们。系统启动时,检查任何“待处理”订单,仔细检查是否付款成功,然后放票或确认订单
    • 那里有一个潜在的竞争条件:订单可能正在等待中,付款尚未完成,我们释放门票,然后付款完成
    • 是的,支付 API 允许幂等请求。我想一个有效的解决方案是定期清理数据库中任何 > x 时间前的挂单。然后将这些票添加回池中,这可以在交易中完成。
    猜你喜欢
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多