標籤:
Redis Util實現
package test.jedis;import java.util.List;import java.util.Set;import redis.clients.jedis.Jedis;import redis.clients.jedis.Transaction;public class JedisUtil {public static Jedis redis = new Jedis("localhost", 6379);// 串連redisstatic{//初始化購物資料redis.set("buy:number:1", "10000");}/** * 執行事務的過程其他用戶端改變了其中的key值,解決資料一致性問題 * 通過watch 對key的監控來實現其他用戶端修改資料後,事務取消 * 用法 首先用watch 開始對key的監控 在開啟事務,順序一定要先監控在執行事務 * */public synchronized static String buy_trans(String userId) throws InterruptedException{//1、通過對keys 的設計保證 每個使用者只能購買一個 if(!redis.exists(userId)){//2、當數量不購時提示 秒殺完 if(Integer.parseInt(redis.get("buy:number:1"))>0){ //3、redis 事務 監控數量的變化key=buy:number:1 監控1號商品的數量變化 redis.watch("buy:number:1"); //4、開啟事務 Transaction tx = redis.multi(); //5、購買使用者購買 成功 成功購買 tx.incr(userId); //6、設定數量減1 tx.decr("buy:number:1"); //7、執行事務 List<Object> results = tx.exec(); }else{ return "數量不足"; } redis.disconnect(); return "搶購購買成功";}else{return "該使用者已經購買了";}}public static Set<String> getKeys(String keys){return redis.keys(keys);}}
Controller 端實現
package com.sf.fs.view;import java.util.Set;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.sf.fs.service.SeckillService;/** * seckill test * */@Controllerpublic class SeckillController {private SeckillService seckillService;public void setSeckillService(SeckillService seckillService) {this.seckillService = seckillService;}/** * 搶購方法 * */@RequestMapping("/buying")public String buying(HttpServletRequest req){//測試用於方便測試用sessionid 作為使用者id String sessionId=req.getSession().getId();//儲存的key 是 user:sessionIdString msg=seckillService.buying("user:"+sessionId);System.out.println("返回的操作結果:"+msg);return "succeed";}/** * 測試成功搶購的使用者數,是否會出現超賣 * */@RequestMapping("/result")public void getResult(HttpServletRequest req){Set<String> sets=seckillService.getUsers("user:*");System.out.println("成功秒殺到的使用者數:"+sets.size());}}
Service 實現
package com.sf.fs.service.impl;import java.util.List;import java.util.Set;import com.sf.fs.service.SeckillService;import test.jedis.JedisUtil;public class SeckillServiceImpl implements SeckillService {public static int number=100;private JedisUtil jedisUtil;public void setJedisUtil(JedisUtil jedisUtil) {this.jedisUtil = jedisUtil;}@Overridepublic String buying(String key) {try {return jedisUtil.buy_trans(key);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}return "操作失敗";}public Set<String> getUsers(String prefixKey){return jedisUtil.getKeys(prefixKey);}}
Redis-秒殺情境應用