下单支付流程
1.选择商品添加至购物车。
2.点击支付,创建订单。
3.将订单写入数据库。
4.同时扣减库存,将订单数据同时同步到redis,并且设置过期时间。
5.取消订单(超时未支付),退回商品库存。
6.定时清理未支付异常订单,退回商品库存。
订单中遇到的问题:
1.重复下单,恶习重复下单,
采取的接口的幂等性+token验证机制,自定义token注解,实现token的创建和删除功能,创建拦截器继承处理器拦截适配器,重写prehandle方法,在下单之后请求处理钱完成拦截处理,下单生成自定义token将其存储在redis缓冲中的session中,并且将其返回响应给客户端,客户端下次请求会携带token作为请求头发送请求,请求进入到拦截器进行前端请求获取token,如果token不存在则进行创建token,同时成功创建订单,保存在redis缓冲中等待库存的扣减和订单超时管理删除订单,如果存在,则处理拦截适配器进行拦截,返回不允许重复下单。
2.如何安全扣减库存,不超卖不少卖
采用springboot操作redisbution实现对库存字段分布式锁机制,利用redission框架,set key value nx方法设置延时时间,当有很
多请求发过来时,会一个一个请求来执行,因为redis是单线程架构,系统宕机完成自动释放库存锁。解决了由于系统宕机锁未释放,还有释放锁异常采用try cath final。释放锁和删除锁。
@RestController
public class IndexController {
@Autowired
private Redisson redisson;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping("/deduct_stock")
public String deductStock(){
String lockKey="lockKey";
RLock redisId=redisson.getLock(lockKey);//拿到锁对象
try {
//问题一
redisId.lock();//j加锁
int stock=Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get("stock");
if(stock>0){
int realStock=stock-1;
stringRedisTemplate.opsForValue().set("stock",realStock+"");//jedis.set(key,value)
}else{
System.out.printl