zoukankan      html  css  js  c++  java
  • Redis 扛 Mysq 并发方案小记

    前些日子的业务系统出现了并发现象, 我们的订单表由于对做对第三方开放的接口平台 而增加了 第三方的订单号 而这个订单号只能保证在该商户下唯一, 整个列中并不唯一, 且我们之前的订单由于没 第三方订单号 而为空, 因此没法建组合唯一索引

    利用 Redis 的 setnx 特性可以构建一个锁机制, 以下是实现的部分片段

     public static function Block($key, $action = TRUE, $options = [])
        {
            if(!defined('MERCHANT_TOKEN')) return FALSE;
            $res = FALSE;
            $redis = Yii::$app->redis;
            // 前缀
            $prefix = isset($options['prefix']) ? (string)$options['prefix'] : 'MOSN';
            // 过期时间
            $expire = isset($options['expire']) ? (integer)$options['expire'] : 300;
            $key = vsprintf('%s:%s:%s', [$prefix, MERCHANT_TOKEN, $key]);
            if ($action === TRUE){
                $res = $redis->executeCommand('SETNX', [$key, time() + $expire]);
                if ($res){
                    $redis->executeCommand('EXPIRE', [$key, $expire]);
                }
            }else if ($action === FALSE){
                $res = $redis->executeCommand('DEL', [$key]);
            }
            return $res ? TRUE : FALSE;
        }
    
    

    优化后

     public static function Block($key, $action = TRUE, $options = [])
        {
            if(!defined('MERCHANT_TOKEN')) return FALSE;
            $res = FALSE;
            $redis = Yii::$app->redis;
            // 前缀
            $prefix = isset($options['prefix']) ? (string)$options['prefix'] : 'MOSN';
            // 过期时间
            $expire = isset($options['expire']) ? (integer)$options['expire'] : 300;
            $key = vsprintf('%s:%s:%s', [$prefix, MERCHANT_TOKEN, $key]);
            $timeNow = time();
            if ($action === TRUE){
                if ($redis->executeCommand('SETNX', [$key, $timeNow + $expire]) || $redis->executeCommand('GET', [$key]) && $redis->executeCommand('GETSET', [$key, $timeNow + $expire + 1]) < $timeNow){
                    $res = TRUE;
                }else{
                    $res = FALSE;
                }
            }else if ($action === FALSE){
                $redis->executeCommand('SET', [$key, $timeNow]);
                $res = TRUE;
            }
            $redis->executeCommand('EXPIRE', [$key, $expire]);
            return $res;
        }
    
  • 相关阅读:
    java代码--Date类获取当前时间-格式化输出
    Eclipse快速生成do while if 等方法
    java不同包中protected修饰的属性和方法调用方法
    java中如果删除导入的jar包,工程出现叹号解决方案
    Best Reward HDU 3613(回文子串Manacher)
    Teacher YYF
    Period II
    How many
    String Problem
    Corporate Identity
  • 原文地址:https://www.cnblogs.com/dongyanglv/p/6767476.html
Copyright © 2011-2022 走看看