redis使用watch秒杀抢购实现思路

本文实例为大家分享了redis使用watch秒杀抢购的具体代码,供大家参考,具体内容如下

1、使用watch,采用乐观锁
2、不使用悲观锁,因为等待时间非常长,响应慢
3、不使用队列,因为并发量会让队列内存瞬间升高

代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import redis.clients.jedis.Jedis;

/**
 * redis测试抢购
 *
 * @author 10255_000
 *
 */
public class RedisTest {
 public static void main(String[] args) {
  final String watchkeys = "watchkeys";
  ExecutorService executor = Executors.newFixedThreadPool(20);

  final Jedis jedis = new Jedis("192.168.3.202", 6379);
  jedis.set(watchkeys, "0");// 重置watchkeys为0
  jedis.del("setsucc", "setfail");// 清空抢成功的,与没有成功的
  jedis.close();

  for (int i = 0; i < 10000; i++) {// 测试一万人同时访问
   executor.execute(new MyRunnable());
  }
  executor.shutdown();
 }
}

import java.util.List;
import java.util.UUID;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class MyRunnable implements Runnable {

 String watchkeys = "watchkeys";// 监视keys
 Jedis jedis = new Jedis("192.168.3.202", 6379);

 public MyRunnable() {
 }

 @Override
 public void run() {
  try {
   jedis.watch(watchkeys);// watchkeys

   String val = jedis.get(watchkeys);
   int valint = Integer.valueOf(val);
   String userifo = UUID.randomUUID().toString();
   if (valint < 10) {
    Transaction tx = jedis.multi();// 开启事务

    tx.incr("watchkeys");

    List<Object> list = tx.exec();// 提交事务,如果此时watchkeys被改动了,则返回null
    if (list != null) {
     System.out.println("用户:" + userifo + "抢购成功,当前抢购成功人数:"
       + (valint + 1));
     /* 抢购成功业务逻辑 */
     jedis.sadd("setsucc", userifo);
    } else {
     System.out.println("用户:" + userifo + "抢购失败");
     /* 抢购失败业务逻辑 */
     jedis.sadd("setfail", userifo);
    }

   } else {
    System.out.println("用户:" + userifo + "抢购失败");
    jedis.sadd("setfail", userifo);
    // Thread.sleep(500);
    return;
   }

  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   jedis.close();
  }

 }

}

Redis对事物的支持目前比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,但后面命令出错前面不会回滚。而中间不会插入其他client的命令。当一个client在找一个连续中发出multi命令时,这个链接会进入一个事务上下文,该链接后续的命令不会立即执行,而是先放到队列中,当执行exec命令是,redis会顺序的执行队列中的所有命令。当如果队列中有命令错误,不会回滚。

乐观锁:大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个”version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号+1。此时,将提交数据的版本号与数据库表对应记录版本号进行比对,如果提交的数据版本号大于数据当前版本号,则予以更新,否则认为是过去数据。

在Redis中,使用watch命令实现乐观锁(watch key):
watch命令会监视给定的key,当exec时,如果监视的key从调用watch后发生过变化,则事务会失败,也可以调用wathc多长监视多个key。这样就可以对指定key加乐观锁了。注意watch的可以是对整个连接有效的。事务也一样。如果连接断开,监视和事务都会被自动清除。当然exec,discard,unwatch命令都会清除连接中的所有监视。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • php+redis实现商城秒杀功能
  • yii框架redis结合php实现秒杀效果(实例代码)
  • Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境
  • php结合redis实现高并发下的抢购、秒杀功能的实例
  • 基于redis分布式锁实现秒杀功能
(0)

相关推荐

  • Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境

    秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购,我们生活的方方面面都可以看到秒杀的身影.秒杀的架构设计也是对于一个架构师架构设计能力的一次考验.本文的目的并不在于提供一个可以直接落地的设计方案,而是意在提供一个简单的方法,一个思路,使大家能够对于秒杀背后的一些设计有更感性的认识, 并且可以自己亲自动手实践一下.所有的配置及源码都在本文最后的GitHub repository中可以找到. 首先,先简单介绍下本文中会涉及到的一些组件,如下图所示: JMeter:用JMeter来模拟

  • yii框架redis结合php实现秒杀效果(实例代码)

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <?php namespace backend\controllers; use Yii; use yii\web\Controller; /** * */ class GoodsController extends Controller { public $enableCsrfValidation=false; public function actionInfo() { $data=yii::$app->db->createCom

  • php结合redis实现高并发下的抢购、秒杀功能的实例

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis. 重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数 <?php $conn=mysql_connect("localho

  • php+redis实现商城秒杀功能

    好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1.安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1.安装php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: 1.2.php.ini文件新增extension=php_igbinary.dll;extension=php_redis.dll两处扩展 ok此处已经完成第一步redis环境搭建完成看看phpinfo 2.项目中实际使

  • 基于redis分布式锁实现秒杀功能

    最近在项目中遇到了类似"秒杀"的业务场景,在本篇博客中,我将用一个非常简单的demo,阐述实现所谓"秒杀"的基本思路. 业务场景 所谓秒杀,从业务角度看,是短时间内多个用户"争抢"资源,这里的资源在大部分秒杀场景里是商品:将业务抽象,技术角度看,秒杀就是多个线程对资源进行操作,所以实现秒杀,就必须控制线程对资源的争抢,既要保证高效并发,也要保证操作的正确. 一些可能的实现 刚才提到过,实现秒杀的关键点是控制线程对资源的争抢,根据基本的线程知识,可

  • redis使用watch秒杀抢购实现思路

    本文实例为大家分享了redis使用watch秒杀抢购的具体代码,供大家参考,具体内容如下 1.使用watch,采用乐观锁 2.不使用悲观锁,因为等待时间非常长,响应慢 3.不使用队列,因为并发量会让队列内存瞬间升高 代码: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import redis.clients.jedis.Jedis; /** * redis测试抢购 * *

  • Redis使用watch完成秒杀抢购功能的代码

    redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内存数据库来抢购速度极快. 2. 速度快并发自然没不是问题. 3. 使用悲观锁,会迅速增加系统资源. 4. 比队列强的多,队列会使你的内存数据库资源瞬间爆棚. 5. 使用乐观锁,达到综合需求. 我觉得以下代码肯定是你想要的. <?php header("content-type:text/htm

  • php+redis消息队列实现抢购功能

    本文实例为大家分享了php+redis消息队列实现抢购的具体代码,供大家参考,具体内容如下 实现功能: 1. 基于redis队列,防止高并发的超卖 2. 基于mysql的事务加排它锁,防止高并发的超卖 基于redis队列工作流程: 1. 管理员根据goods表中的库存,创建redis商品库存队列 2. 客户端访问秒杀API 3. web服务器先从redis的商品库存队列中查询剩余库存重点内容 4. redis队列中有剩余,则在mysql中创建订单,去库存,抢购成功 5. redis队列中没有剩余

  • Thinkphp5+Redis实现商品秒杀代码实例讲解

    环境:wamp,redis 要求:安装WAMP,Redis,以及为PHP安装Redis扩展 秒杀功能大致思路:获取缓存列表的长度,如果长度(llen)等于0,就停止秒杀,即秒杀失败,如果长度大于0,则继续运行,先从缓存中移除一个元素(lpop),再进行数据库操作(添加订单表,商品库存数量减一),如果再进一个人秒杀,就再走一遍流程,循环往复. 一.安装Redis扩展 1.查看PHP版本信息 打开phpinfo.php,查看PHP版本,我的是PHP7.3.4,还有一个需要注意Architecture

  • 自制Python淘宝秒杀抢购脚本双十一百分百中

    大家好,我是不学前端的前端程序员, 事情是这个样子的,前几天不是双十一预购秒杀嘛 由于我女朋友比较笨,手速比较慢,就一直抢不到,她没抢到特价商品就不开心, 她不开心,我也就不能跟着开心,就别提看6号的全球总决赛了 为了解决这个问题,就决定写一个自动定时抢购的脚本. 第一步: 首先我的思路很简单,就是让"程序"帮我们自动打开浏览器,进入淘宝,然后到购物车等待抢购时间,自动购买并支付. 第二步: 导入模块,我们需要一个时间模块,抢购的时间,还有一个Python的自动化操作. 代码如下: i

  • redis 实现登陆次数限制的思路详解

    title: redis-login-limitation  利用 redis 实现登陆次数限制, 注解 + aop, 核心代码很简单. 基本思路 比如希望达到的要求是这样: 在 1min 内登陆异常次数达到5次, 锁定该用户 1h 那么登陆请求的参数中, 会有一个参数唯一标识一个 user, 比如 邮箱/手机号/userName 用这个参数作为key存入redis, 对应的value为登陆错误的次数, string 类型, 并设置过期时间为 1min. 当获取到的 value == "4&qu

  • PHP+redis实现的限制抢购防止商品超发功能详解

    本文实例讲述了PHP+redis实现的限制抢购防止商品超发功能.分享给大家供大家参考,具体如下: redis不仅仅是单纯的缓存,它还有一些特殊的功能,在一些特殊场景上很好用.redis中key的原子自增incrby和判断key不存在再写入的setnx方法,可以有效的防止超发. 下面使用两个不同的方式来说明利用redis做商品购买库存数量限制. 业务场景很简单,就是限制抢购5个商品,模拟并发请求抢购商品,每抢购一次对应redis中的key值增加一次,通过判断限购的数量来限制抢购,抢购成功写入成功日

  • springboot集成redis实现简单秒杀系统

    本文实例为大家分享了springboot集成redis实现简单秒杀系统的具体代码,供大家参考,具体内容如下 项目是有地址的,我会放到文章的最后面 1. 直接service,我们会介绍两种秒杀模式 public interface GoodsService { /** * 通过lua脚本实现的秒杀 * @param skuCode 商品编码 * @param buyNum 购买数量 * @return 购买数量 */ Long flashSellByLuaScript(String skuCode

  • 如何利用 JS 脚本实现网页全自动秒杀抢购功能

    倒计时页面: 倒计时未结束时,购买按钮还不能点击. 结束时,可以点击购买,点击后出现提示"付款成功" 展示效果 GIF 1.制作测试网页 首先我们来做一个简易的抢购页面 <!DOCTYPE html> <html lang="zh_CN"> <head> <meta charset="UTF-8"> <title>Apple</title> <style type=&q

随机推荐