当前位置: 首页 > news >正文

高端网站建设费用鹤壁seo

高端网站建设费用,鹤壁seo,网站建设与维护实训报告,新桥专业网站建设1、目的 使用lua脚本,可以保证多条命令的操作原子性;同时可以减少操作IO(比如说判断redis对应数据是否小于0,小于0就重置为100,这个场景一般是取出来再判断,再存放进行,就至少存在2次IO,用lua脚…

1、目的

        使用lua脚本,可以保证多条命令的操作原子性;同时可以减少操作IO(比如说判断redis对应数据是否小于0,小于0就重置为100,这个场景一般是取出来再判断,再存放进行,就至少存在2次IO,用lua脚本一条命令1次IO就解决了,在批量扣减情况存在多次IO,lua脚本1次也可以解决),提高速度,降低IO.

2、使用案列

        根据传入的产品标识及数量扣减该产品数量;此处为单个产品扣减,可优化为批量产品传入,lua内部用table处理。

2.1 初始化redis参数

添加产品及库存(hash结构)。添加两种水果的库存。

// 向Redis中添加数据
redisTemplate.opsForHash().put("productMap", "pro1", "{\"name\":\"苹果\",\"stock\":100}");
redisTemplate.opsForHash().put("productMap", "pro2", "{\"name\":\"西瓜\",\"stock\":1200}");

查看结果:

2.2 业务代码

传入lua脚本,实现对应产品库存数量扣减。(可优化为多产品批量扣减)

通过setnx加锁,防止死锁设置锁超时时间,同时业务执行完手动释放锁。设置锁等待时间、及锁等待轮询获取锁。(eg:自旋释放cpu资源重新抢占资源)

@Test
public void tete(){// 向Redis中添加数据redisTemplate.opsForHash().put("productMap", "pro1", "{\"name\":\"苹果\",\"stock\":100}");redisTemplate.opsForHash().put("productMap", "pro2", "{\"name\":\"西瓜\",\"stock\":1200}");// Lua 脚本字符串    String luaScript = "local productKey = KEYS[1]; " +"local pro = KEYS[2]; " +"local lockKey = KEYS[3]; " +"local lockTimeout = tonumber(ARGV[1]); " +"local deductAmount = tonumber(ARGV[2]); " +"local spinIntervalMs = tonumber(ARGV[3]); " +"local maxSpinCount = tonumber(ARGV[4]); " +"local lockAcquired = redis.call('setnx', lockKey, 1); " +"if lockAcquired == 1 then " +"    redis.call('pexpire', lockKey, lockTimeout); " +"    local currentValue = redis.call('hget', productKey, pro); " +"    if currentValue then " +"        local dbObj = cjson.decode(currentValue);" +"        local currentStock = tonumber(dbObj.stock); " +"        if currentStock >= deductAmount then " +"            dbObj.stock = currentStock - deductAmount; " +"            local updatedValue = cjson.encode(dbObj); " +"            redis.call('hset', productKey, pro, updatedValue); " +"            redis.call('del', lockKey); " +  // 释放锁"            return true; " +"        else " +"            return false; " +"        end " +"    else " +"        return false; " +"    end " +"else " +"    local spinCount = 0; " +"    while spinCount < maxSpinCount do " +"        local lockValue = redis.call('get', lockKey); " +"        if not lockValue then " +"            lockAcquired = redis.call('setnx', lockKey, 1); " +"            if lockAcquired == 1 then " +"                redis.call('pexpire', lockKey, lockTimeout); " +"                local currentValue = redis.call('hget', productKey, pro); " +"                if currentValue then " +"                   local dbObj = cjson.decode(currentValue);" +"                   local currentStock = tonumber(dbObj.stock); " +"                    if currentStock >= deductAmount then " +"                        dbObj.stock = currentStock - deductAmount; " +"                        local updatedValue = cjson.encode(dbObj); " +"                        redis.call('hset', productKey, pro, updatedValue); " +"                        redis.call('del', lockKey); " +  "                        return true; " +"                    else " +"                        return false; " +"                    end " +"                else " +"                    return false; " +"                end " +"            end " +"            break; " +"        end " +"        spinCount = spinCount + 1; " +"    end " +"    return false; " +"end";// 创建DefaultRedisScript对象DefaultRedisScript<Boolean> script = new DefaultRedisScript<>();script.setScriptText(luaScript);script.setResultType(Boolean.class); // 设置返回类型为Boolean// 执行脚本Boolean result = (Boolean) redisTemplate.execute(script,Collections.unmodifiableList(List.of("productMap","pro1","lock:pro1")), // KEYS参数"50000", // ARGV参数第一个:锁过期时间(毫秒)"10", // ARGV参数第二个:扣减数量"1000",// ARGV参数第3个:等待时间"5");// ARGV参数第4个:轮询次数System.out.println("result1:"+result);Boolean result2 = (Boolean) redisTemplate.execute(script,Collections.unmodifiableList(List.of("productMap","pro1","lock:pro1")), // KEYS参数"50000", // ARGV参数第一个:锁过期时间(毫秒)"10", // ARGV参数第二个:扣减数量"1000","5");System.out.println("result2:"+result2);Boolean result3 = (Boolean) redisTemplate.execute(script,Collections.unmodifiableList(List.of("productMap","pro1","lock:pro1")), // KEYS参数"50000", // ARGV参数第一个:锁过期时间(毫秒)"10", // ARGV参数第二个:扣减数量"1000","5");System.out.println("result3:"+result3);if (result2) {System.out.println("Stock deduction successful.");} else {System.out.println("Insufficient stock or lock already acquired.");}// 验证库存是否正确扣减Object updatedValue = redisTemplate.opsForHash().get("productMap", "pro1");System.out.println(updatedValue);Boolean result5 = (Boolean) redisTemplate.execute(script,Collections.unmodifiableList(List.of("productMap","pro2","lock:pro2")), // KEYS参数"5000", // ARGV参数第一个:锁过期时间(毫秒)"500", // ARGV参数第二个:扣减数量"1000","5");
}

2.3 正常执行结果

2.4 若获取锁超时,则会出现扣减失败

脚本执行时间过长会导致。(此处可通过删除手动释放锁实现:模拟业务耗时过长没办法手动释放锁需等待锁国企时间)

第二个扣减等待超时。可通过设置调整添加自旋时间重试或业务代码判断重试机制

http://www.hkea.cn/news/203000/

相关文章:

  • 乐清做网站哪家好税收大数据
  • 校园网站建设需求天津放心站内优化seo
  • 哈尔滨微网站建设热搜在哪里可以看
  • 网站用oracle做数据库福州seo推广服务
  • 康保县城乡建设委员会网站营销型网站重要特点是
  • 手机做网站的步骤跨境电商有哪些平台
  • 请人做网站要多少网络事件营销
  • 网站页脚有什么作用厦门seo哪家强
  • 东莞百度提升优化优化推广网站推荐
  • 查企业网站有哪些站长统计app软件
  • 做a高清视频在线观看网站济源新站seo关键词排名推广
  • 刚做的网站怎么搜索不出来百度seo收录软件
  • 视频拍摄app站长工具seo综合查询广告
  • 新闻单位建设网站的意义武汉seo推广优化
  • 低价网站公司软文怎么写
  • 东莞市建设公共交易中心网站百度官网首页
  • 如何建立的网站能争钱优化营商环境 助推高质量发展
  • 做百度网站营销型网站建设排名
  • 网站域名被黑国际新闻最新消息战争
  • 苏州网站开发公司济南兴田德润厉害吗网络自动推广软件
  • 广药网站建设试卷株洲最新今日头条
  • 网站建设管理考核办法微信推广平台怎么做
  • 网站新闻模块代码网络推广有哪些常见的推广方法
  • 合肥大型网站如何推广普通话
  • 高端网站制作软件怎么样推广自己的店铺和产品
  • 无障碍浏览网站怎么做关键词seo排名优化推荐
  • wordpress 247seo推广系统
  • 做深圳门户网站起什么名字好泰州seo外包公司
  • 网站视频上传怎么做百度站长平台论坛
  • wordpress农业模板下载小时seo