Redis事务

发布时间 2023-12-28 10:06:21作者: 朝阳1

其实redis的事务是个假事务,没有实现原子性,

若要php支持事务,必须一起执行,其中incr会报错

$status =  $redis->multi()->lPush($key1, '1123')->lPush($key2, '2123')->incr("age","age")->exec();
try {
    $redis = new Redis();
    $redis->connect('192.168.75.132', 6379);
    //开启事务
    $redis->multi();
    $redis->setex('keyTest', 60, 1);
    $redis->get('keyTest');
    $redis->incr('keyTest');
    $redis->get('keyTest');
    //执行事务
    $ret = $redis->exec();
    print_r($ret);
} catch (Exception $e){
    echo $e->getMessage();
}
//输出
Array
(
    [0] => 1
    [1] => 1
    [2] => 2
    [3] => 2
)

取消事务

try {
    $redis = new Redis();
    $redis->connect('192.168.75.132', 6379);
    //先设置缓存keyTest为1
    $redis->setex('keyTest', 60, 1);
    //开启事务
    $redis->multi();
    $redis->setex('keyTest', 60, 10);
    $redis->get('keyTest');
    $redis->incr('keyTest');
    $redis->get('keyTest');
    //取消事务
    $redis->discard();
    $ret = $redis->get('keyTest');
    var_dump($ret);
    //查看keyTest
} catch (Exception $e){
    echo $e->getMessage();
}
//输出
string(1) "1"

监视键,并执行事务

try {
    $redis = new Redis();
    $redis->connect('192.168.75.132', 6379);
    //先设置缓存keyTest为1
    $redis->setex('keyTest', 60, 1);
    //监视keyTest
    $redis->watch(array('keyTest'));
    //假设在开始监视之后,执行事务之前,keyTest被并发操作redis的其他用户修改了
    $redis->setex('keyTest', 60, 10);
    //开启事务
    $redis->multi();
    $redis->incr('keyTest');
    //执行事务
    $ret = $redis->exec();
    var_dump($ret);
    $ret = $redis->get('keyTest');
    var_dump($ret);
    //查看keyTest
} catch (Exception $e){
    echo $e->getMessage();
}
//输出 
bool(false)
string(2) "10"

redis抢购

<?php
header("content-type:text/html;charset=utf-8");
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->watch("mywatchlist");
$len = $redis->hlen("mywatchlist");
$rob_total = 100; //抢购数量
if ($len < $rob_total) {
    $redis->multi();
    $redis->hSet("mywatchlist", "user_id_" . mt_rand(1, 999999), time());
    $rob_result = $redis->exec();
    //file_put_contents("log.txt", $len . PHP_EOL, FILE_APPEND);
    if ($rob_result) {
        $mywatchlist = $redis->hGetAll("mywatchlist");
        echo '抢购成功' . PHP_EOL;
        echo '剩余数量:' . ($rob_total - $len - 1) . PHP_EOL;
        echo '用户列表:' . PHP_EOL;
        print_r($mywatchlist);
        exit;
    } else {
        exit('手气不好,再抢购!');
    }
} else {
    exit('已卖光');
}