我以前遇到过这个,这是我做的:
使用远程过程调用拆分本地事务。
如果订单发送失败,我认为这没什么大不了的。在这种情况下,要么下单但未设置为“已发送”,要么回滚订单。如果订单未发送,则业务操作员可以进行干预,如果未下订单,则客户将致电。
但是下单成功后如果交易出现问题就很烦了。在这种情况下,如果订单被回滚,干预会更加困难,因为我们丢失了供应商的通知。通知通常包含供应商的订单标识符,因此我们可以在必要时取消带有此标识符的订单。
所以我们决定使用消息传递。
1) PlaceOrderService 负责存储订单并发送消息。
2)消息的消费者将订单发送给供应商,并发送包含供应商通知的消息。
3)通知消息的其他消费者更新订单状态。
每个步骤仅修改一个聚合或仅调用远程。
希望这可以帮助。
更新
1.你将如何在这里实现消息传递部分
我采用 Eric Evans 的 dddsample ApplicationEvents 中提到的解决方案。它只是一个简单的接口和一个 jms 实现,比如
public void placeOrder(...) {// method in application service
....//order making
orderRepository.store(order);
applicationEvents.orderWasPlaced(order);//injected applicationEvents
//better move this step out of transaction boundary if not using 2pc commit
//make the method returnning order and use decorator to send the message
// placeOrder(...) {
// Order order = target.placeOrder(...);//transaction end here
// applicationEvents.orderWasPlaced(order);
// return order;
// }
}
public class JmsApplicationEvents implements ApplicationEvents {
public void orderWasPlaced(Order order) {
//sends the message using messaging api of your platform
}
}
2.I see you mention suppliers notification, but let's assume this is done through email (which will be the primary scenario here) I would
like to know that the transaction was performed without errors (i.e.
no smtp or connection failure), but cannot rely on a response that the
order was actually received would that change anything?
hmm.. I have never build an trading application based on email, but here is my suggestions:
Messaging solution still fits if you need strong consistency. Messaging is transactional and could involve in global transaction while email doesn't.
Messaging provides more availability (your order making will not fail even if the mailserver is down) and scalability(queues).
Failure handling is more difficult in messaging solution, usually needs compensating actions. And it's more difficult for the user to get the processing information. For example, you have to notify the user about the progress of the order processing since the following steps are asynchronous. And an email should be sent to the customer if the order is rejected by the supplier.
But messaging does add extra complexity and takes you more effort to build and maintain. You have to evaluate is the gain worth the cost. Actually, I have also built several systems in synchronous solution(they don't require high throughput and availability), they works fine most of the time, only less than ten of orders fail due to the connection problem within a year, so it's not worthy to build an automatic error handling mechanism at all.