【问题标题】:Handle asynchronous notifications in a specific order按特定顺序处理异步通知
【发布时间】:2023-03-15 02:34:01
【问题描述】:

我正在使用 javax.servlet 来获取有关用户完成付款状态的异步通知。 每个通知都包含需要在数据库中更新的信息,例如 - 用户详细信息、支付金额、支付 ID、支付状态等...

例如,一组 id=1 的付款通知:

{user_msisdn='',      amount_paid=0.00, payment_id = 1, payment_state=NEW}
{user_msisdn=0012345, amount_paid=0.00, payment_id = 1, payment_state=PENDING}
{user_msisdn=0012345, amount_paid=2.00, payment_id = 1, payment_state=COMPLETED}

即使通知是异步的,数据库更新必须按顺序进行,所以当我更新我的支付表时,id = 1 的支付条目必须首先更新为状态' NEW',然后到 'PENDING',然后到 'COMPLETED'。
在我的代码中针对每个 payment_state 完成了一些其他内部操作,因此这不仅仅是关于交易管理。

我的问题是,有时这些通知会以毫秒为间隔到达,在这种情况下,当“新”通知等所需的操作尚未完成,然后“PENDING”到达时,数据库可能首先更新为“PENDING”状态,然后被“NEW”覆盖...

我正在寻找一种解决方案,该解决方案将同时处理不同付款 ID 的通知,但具有相同付款 ID 的通知按收到的相同顺序依次处理。

  • 当前的实现在通知处理方法周围使用了一个方面,这可以防止同时执行对相同 payment_id 的调用。但我正在寻找更好的解决方案
  • 我曾考虑过使用 ActiveMQ,但是我必须为每个 payment_id 创建队列/主题,这太过分了。
  • 我还阅读了一些关于 Spring Reactor 的内容,但我不确定是否可以为每个 payment_id 动态创建调度程序
  • 也许在 payment_id 上使用一些锁会阻止其他具有相同 payment_id 的通知在完成之前被处理?
  • 还有其他想法吗?

谢谢!

【问题讨论】:

    标签: java spring asynchronous servlets project-reactor


    【解决方案1】:

    请看一下生产者-消费者的概念

    wiki/Producer–consumer_problem

    producer-consumer-pattern

    如果您必须按特定顺序处理事件,您应该考虑一个能够排序/忽略传入事件的消费者,如果您的订单要求不符合。

    如果您发现像 PENDING 在 NEW 之前这样的损坏订单,则将 PENDING 再次添加到队列的末尾。下一个将是新的,您可以执行此操作。下一个传入是 COMPLETED,但由于尚未调用 PENDING,因此您将 COMPLETE 也放在队列的末尾,并且订单有效。

    当然,您必须注意丢失的事件。否则,您总是会无缘无故地再次添加事件,但这是一种特殊的错误处理逻辑。

    【讨论】:

    • 您好,感谢您的回答!我也考虑过使用队列,但是我必须为每个 payment_id 创建一个队列,因为我只关心相同 payment_id 的通知顺序。每秒可能有数百个队列,在处理此付款后将不再使用,因为每个 payment_id 都是唯一的,所以我需要以某种方式丢弃它们。是不是有点开销?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多