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;
    }

转载于:https://www.cnblogs.com/dongyanglv/p/6767476.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值