网站首页php

Redis分步锁解决Mysql并发处理问题

发布时间:2023-01-13 15:14:07编辑:slayer.hover阅读(56)

    1. 测试高并发写数据库, 要过滤掉重复数据, 在插入之前判断有无此数据.

    if (DB::Table('record')->where('event_id', $event_id)->exists()) {
        //插入数据
    }

    但偶尔还是有重复数据写入, 不考虑加唯一索引的情况下, 需要使用同步锁来控制一下流程.


    2. Redis分步锁, 代码如下所示:

    function sync($key, callable $func, $expire = 10000)
    {
        if (!$cache_enable) {
            $result = call_user_func($func);
        }else {
            $random = uniqid($key) . rand(0, 1000000);
            while (!Cache::set($key, $random, ['nx', 'px' => $expire])) {
                usleep(100000);
            }
            $result = call_user_func($func);
            if (Cache::get($key) == $random) {
                Cache::delete($key);
            }
        }
        return $result;
    }

    备注:  Redis不可用则返回原流程.

    Cache::set($key, $random, ['nx', 'px'=>$expire]);

    $key不存在时写入, 并设置$expire毫秒后自动过期. 写入成功则返回TRUE;

    未加锁成功, 则100毫秒后重试.   加锁成功后执行业务流程, 完成后释放当前锁.

    3. 使用方法:

    sync('lock001', function (){
        if (DB::Table('record')->where('event_id', $event_id)->exists()) {
        //插入数据...
        }
    });

    如此, 即可解决同步写入的问题.


评论