按特定顺序处理异步通知
Handle asynchronous notifications in a specific order
我正在使用 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}
即使通知是异步的,数据库更新必须按顺序,所以当我更新付款时table,id = 1 的付款条目必须首先更新为状态“NEW”,然后更新为“PENDING”,然后更新为“COMPLETED” .
我的代码中为每个 payment_state 完成了一些其他内部操作,因此这不仅仅是关于 事务管理。
我的问题是,有时这些通知会以毫秒为间隔到达,在这种情况下,当 'NEW' 通知等所需的操作尚未完成时,然后 'PENDING' 到达时,数据库可能首先更新为 'PENDING' 状态,然后被 'NEW' 覆盖...
我正在寻找一种解决方案,该解决方案将同时处理不同付款 ID 的通知,但具有相同付款 ID 的通知将按收到的相同顺序依次处理。
- 当前的实现是围绕通知处理方法使用方面,这可以防止同时执行对相同 payment_id 的调用。但我正在寻找更好的解决方案
- 我考虑过使用 ActiveMQ,但我必须为每个 payment_id 创建队列/主题,这太过分了。
- 我也阅读了一些关于 Spring Reactor 的内容,但我不确定我是否可以为每个 payment_id 动态创建一个调度程序
- 也许在 payment_id 上使用一些锁,这将阻止具有相同 payment_id 的其他通知在完成之前被处理?
- 还有其他想法吗?
谢谢!
请看一下生产者-消费者的概念
wiki/Producer–consumer_problem
如果您必须按特定顺序处理事件,如果您的顺序要求不适合,您应该考虑一个能够 sort/ignore 传入事件的消费者。
如果您发现一个损坏的订单,例如 PENDING 在 NEW 之前,您再次将 PENDING 添加到队列的末尾。下一个将是新的,这个你可以执行。下一个进来的是COMPLETED,但是因为还没有调用PENDING,所以你把COMPLETE也放到队尾,订单才有效。
当然,您必须注意丢失的事件。否则你有总是无缘无故再次添加的事件,但这是一种特殊的错误处理逻辑。
我正在使用 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}
即使通知是异步的,数据库更新必须按顺序,所以当我更新付款时table,id = 1 的付款条目必须首先更新为状态“NEW”,然后更新为“PENDING”,然后更新为“COMPLETED” .
我的代码中为每个 payment_state 完成了一些其他内部操作,因此这不仅仅是关于 事务管理。
我的问题是,有时这些通知会以毫秒为间隔到达,在这种情况下,当 'NEW' 通知等所需的操作尚未完成时,然后 'PENDING' 到达时,数据库可能首先更新为 'PENDING' 状态,然后被 'NEW' 覆盖...
我正在寻找一种解决方案,该解决方案将同时处理不同付款 ID 的通知,但具有相同付款 ID 的通知将按收到的相同顺序依次处理。
- 当前的实现是围绕通知处理方法使用方面,这可以防止同时执行对相同 payment_id 的调用。但我正在寻找更好的解决方案
- 我考虑过使用 ActiveMQ,但我必须为每个 payment_id 创建队列/主题,这太过分了。
- 我也阅读了一些关于 Spring Reactor 的内容,但我不确定我是否可以为每个 payment_id 动态创建一个调度程序
- 也许在 payment_id 上使用一些锁,这将阻止具有相同 payment_id 的其他通知在完成之前被处理?
- 还有其他想法吗?
谢谢!
请看一下生产者-消费者的概念
wiki/Producer–consumer_problem
如果您必须按特定顺序处理事件,如果您的顺序要求不适合,您应该考虑一个能够 sort/ignore 传入事件的消费者。
如果您发现一个损坏的订单,例如 PENDING 在 NEW 之前,您再次将 PENDING 添加到队列的末尾。下一个将是新的,这个你可以执行。下一个进来的是COMPLETED,但是因为还没有调用PENDING,所以你把COMPLETE也放到队尾,订单才有效。
当然,您必须注意丢失的事件。否则你有总是无缘无故再次添加的事件,但这是一种特殊的错误处理逻辑。