幂等键
业务标识号 +服务器时间戳 + 服务器编号 + 服务器生成的自增编号 + 用户标识序列号
流程图
时序图
表结构
用户表:
主键id
押金状态
账户余额
单号流水表:
主键id
单号,唯一索引
用户id,逻辑外键
钱的流向
状态
伪代码
// 接收到请求public String 处理请求的函数(Integer id){int status = selectDepositStatusById(id);if ( 1 == status ){return // 已缴纳押金响应}else{// 创建单号String order = makeOrder(id);// 业务处理,返回结果return handleOrder();}}@Transactionpublic String handleOrder(String order,Integer id)// 开启事务向单号流水表插入单号try (){if (insertOrder(order)){if (doPay(order)){if (updateDepositStatusById(id)){// 成功缴纳押金// commit}else{// 押金可能已经缴纳,事务回滚}}else{// 支付失败,事务回滚}}}catch(唯一索引重复异常){// 订单已经处理,事务回滚}
问题
流程这里,当支付失败的时候,应该也放到业务单号表中,然后根据支付失败的原因进行决策,比如是因为网络原因还是余额不够,网络原因可能那边已经成功了,但是返回的结果不对(网络错误等),那么再次重试直到获取到结果。如果是余额不够,那么直接返回了,告诉用户余额不足。
当请求过来的时候,先去看看有没有该用户请求失败的订单,如果有,那么就先拿失败的订单请求,然后再根据结果判断。因为请求失败的原因可能有多种,包括网络延迟之类的。
会议记录
常用注解的熟悉
InetAddress.getLocalHost() 获取本地host地址
初始根据host去查询服务实例表中是否已经存在该服务:
- 存在,返回实例的注册id
- 不存在,注册服务
LocalDateTime.now()获取时间
String.format(“%03d”, yiId.getAndIncrement()%1000),格式化输出,位数不够时左侧填充0
流水表中失败的记录,要进行标识,下一次请求过来,先查询是否有失败记录,有,则先拿失败的进行请求,如果还是出现失败什么的,则可以定义一个提示函数,提示需要人工干预
