按特定顺序处理异步通知

时间:2017-04-25 11:40:53

标签: java spring asynchronous servlets project-reactor

我正在使用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的付款条目更新为“',然后是' PENDING ',然后是'已完成'。
我的代码中为每个payment_state执行了一些其他内部操作,因此这不仅仅是关于事务管理。

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

请查看生产者 - 消费者概念

wiki/Producer–consumer_problem

producer-consumer-pattern

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

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

当然,你必须要注意失踪事件。否则,您将拥有始终无缘无故再次添加的事件,但这是一种特殊的错误处理逻辑。