redisトークンメカニズムを用いて電子商取引の秒殺を実現する
2911 ワード
双11当社の秒殺活動(redisトークンメカニズム)
説明:当社はサービス会社であり、電子商取引会社ではないため、在庫削減などの事務操作技術の選択型には関与しない:redisのlistデータ型の「スタック」の特徴は行い、redisは多重io多重化を採用し、メモリベースの単一スレッドデータベースを採用しているため、プログラムが速く、マルチスレッド同時発生による超過販売問題もなく、単純な楽観ロックで秒殺を実現し、ユーザーの大量の失敗問題を形成することもない
ここでは食事時間を利用して簡単なコードを書いて実現していますが、間違っている点が指摘できます.
準備作業:秒殺開始前に、プログラムを事前に利用して秒殺が必要な商品(サービス)をredisのlist.に書き込む.注:一中商品(サービス)一keyは、この商品が50個を秒殺する場合、listに50個の一意の標識(トークン)を格納する.
1.トークンの取得
public boolean miaoshaTokenFromRedis(Integer goodsId, String user) {
String token = (String)redisTemplate.boundListOps("token_goods_"+goodsId).rightPop();
if(token == null || token.equals("")){
return false;
}else{
// ,
String yes = (String)redisTemplate.boundValueOps(token).get();
if(yes != null && yes.equals("yes")) {
System.out.println(" token , ");
redisTemplate.boundListOps("token_goods_"+goodsId).remove(1,token);
return false;
}
//value (token, )---
redisTemplate.boundHashOps("user_token").put(user,{token,new Date()});
return true;
}
}
2.トークンの返却(タイミングタスクは5 sごとに実行)
public boolean returnToken(String user) {
//
String token = (String) redisTemplate.boundHashOps("user_token").get(user);
if(token == null || token.equals("")){
return false;
}else {
// id list
String goodsId = token.split("_")[1];
redisTemplate.boundListOps("token_goods_"+goodsId).leftPush(token);
return true;
}
}
3.支払い成功
public boolean payTokenToOrder(String user) {
//
String token = (String) redisTemplate.boundHashOps("user_token").get(user);
if(token == null || token.equals("")){
return false;
}else {
// token , token token
// redis token
//redisTemplate.boundValueOps("key").setIfAbsent("value")
// key , false, , s value, true
boolean flag = redisTemplate.boundValueOps(token).setIfAbsent("yes");
// token flag=true
if(flag) {
// (f )id
String goodsId = token.split("_")[1];
Order order = new Order();
order.setUser(user);
order.setGoodId(Integer.parseInt(goodsId));
orderMapper.insert(order);
// , , ,
redisTemplate.boundHashOps("user_token").delete(user);// token
redisTemplate.boundListOps("token_goods_" + goodsId).remove(1, token);// token,
}
return true;
}
}