• Redis-秒杀场景应用


    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);// 连接redis
    	
    	static{
    		//初始化购物数据
    		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
     * */
    @Controller
    public 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:sessionId
    		String 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;
    	}
    
    	@Override
    	public  String buying(String key) {
    		
    		try {
    		return 	jedisUtil.buy_trans(key);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return "操作失败";
    	}
    	
    	public Set<String> getUsers(String prefixKey){
    		
    		return jedisUtil.getKeys(prefixKey);
    	}
    
    }
    

      

  • 相关阅读:
    建议自学
    大牛之术
    学习榜样
    .net源码
    练习题
    学习-如何克服拖延
    如何解决困难问题
    最近阅读
    如何学习一门新语言
    安全问题关注博客
  • 原文地址:https://www.cnblogs.com/zuolun2017/p/5621329.html
Copyright © 2020-2023  润新知