This topic created in 1116 days ago, the information mentioned may be changed or developed.
举个例子,支付订单:
1. 将订单状态改为已支付
2. 记录支付数据
3. 调用库存服务的 http api 接口,减库存并发货
以上三个操作,需要是一个原子操作,要么一起成功,要么一起失败。
1 、2 好说,都是数据库操作,一个事务就 ok 。
但 3 是另一个类型的操作。
我想到方案是:
1. 3 放在事务中,3 成功再提交事务,否则回滚。缺点是 3 会卡事务,只适用于流量特别低,3 执行很快的系统。
2. 3 放队列中,失败了重试。缺点有 2:a ,放队列的操作也可能失败,除非放队列的操作也放事务中; b ,3 可能永远不会成功。
16 replies • 2023-05-19 15:59:22 +08:00
 |
|
1
lthon May 19, 2023 via Android
这是分布式事务啊,看有没有大佬回答
|
 |
|
2
hhjswf May 19, 2023 via Android
@ lthon 就这么点事用分布式事务,系统复杂度直接上一个等级
|
 |
|
3
dzdh May 19, 2023
ID 密等
有个协调者负责协调即可。或者是共同消费消息。
|
 |
|
4
zhuzhibin May 19, 2023 via iPhone
如果我请求外部接口中途被退出了,我方数据没有变更,外部系统数据变更了咋搞
|
 |
|
5
dzdh May 19, 2023
httpapi 一般给两个接口。一个根据指定单号查询,一个下单,下单必传业务方自己的单号,并且返回服务的单号(流水号)
下单前先按照业务方已经生成入库的单号进行查询,做同步,防止多下单。
|
 |
|
7
sadfQED2 May 19, 2023 via Android
改一下执行顺序?先扣库存,扣成功了再改状态
|
 |
|
8
kylinC May 19, 2023
最简单的方法是设置一个中间态, 1,2 成功了订单改为支付成功未发货,然后放队列执行 3, 定时检查支付成功未发货订单作为补充.缺点是时效性不高.
|
 |
|
9
wolfie May 19, 2023
支付前,锁库存。 取消支付 or 支付失败,回滚库存。
|
 |
|
10
wqq096737ink May 19, 2023
异步操作 ,线程 1 先扣库存 ,线程 2 执行事务,根据线程 1 的请求调用是否成功来决定是否提交事务。
如果你觉得线程 2 需要等待线程 1 的结果造成线程 2 事务太长,那么就 扣库存-->订单事务 同步执行。
你的方案 1 中调用接口没必要一定要放到事务中把?
|
 |
|
12
7911364440 May 19, 2023
先执行 3 ,扣库存,库存扣失败直接返回,1 跟 2 直接放在本地事务就 ok 。
|
 |
|
13
opengps May 19, 2023
有个定义叫做“最终一致性”。关于原子性,只要你能保证最终一致性,就可以只在第一步进行控制,也算符合原子性操作
|
 |
|
14
lincanbin May 19, 2023
给订单加个锁,上锁期间禁止所有操作。 全部搞成功再解锁,然后定时去扫出来所有没全部成功的数据出来处理就好了。
|
 |
|
15
wawaguo May 19, 2023
3 改成扣库存 mq 消息,1 、2 、3 放同个事务,最后发送 mq 消息的时候报错就把 12 回滚,不报错就提交事务,需要做业务幂等
|
 |
|
16
CantSee May 19, 2023
哪那么多事,订单创建时候就锁定库存了,到时间再同步释放库存和取消订单,支付时候由于库存是已经锁定的了,只需要关注支付状态就可以了
|