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;
        }
    
  • 相关阅读:
    【Web】Google Chrome 浏览器调试禁用缓存
    js基础(对象)
    js基础
    css
    html
    mybatis(mapper映射文件)
    mybatis(核心配置文件的配置)
    linux三种连接方式
    spring
    mybatis(入门案例)
  • 原文地址:https://www.cnblogs.com/dongyanglv/p/6767476.html
Copyright © 2011-2022 走看看