分布式远程调用:成功,失败,超时。
超时和失败情况,可能会触发重复调用,导致重试,需要被调用接口具有幂等性。
1.排重表:repeat_forbid:
begin transaction;
int flag = insert into repeat_forbid (...biz_id...) value(...biz_id...)
if (flag > 0) {
f(biz_id)
}
commit;
2.业务系统接口根据自己业务来保证幂等。
举例:订单系统和支付系统两个独立系统,订单系统需要调用支付系统接口,
支付系统提供支付接口(用来扣除用户余额)。
1.0版本,会导致相同订单orderId重复消费,导致多次扣款
public boolean pay(accountId,orderMoney) {
begin transaction;
// 扣除用户余额
int flag =update userAmount_table set amount=amount-orderMoney where accountId = accountId and amount>=orderMoney;
if(flag) {
return true;
}else {
return false;
}
commit;
}
2.0版本:支付系统需要记录订单orderId是否已经支付成功过,如果未支付unpay,扣除用户金额,修改订单orderId状态从未支付unpay变成已支付pay;如果支付过,不进行操作。
public boolean pay(accountId,orderId,orderMoney) {
begin transaction;
// update实现防重复
int flag = update order_table set status = pay where accountId = accountId and orderId = orderId and status = unpay;
// 未支付
if(flag > 0) {
// 扣除用户余额
int flag =update userAmount_table set amount=amount-orderMoney where accountId = accountId and amount>=orderMoney;
if(flag) {
return true;
}else {
throw new Exception('用户余额不足');
}
}else {
不进行操作
return false;
}
commit;
}