Predis melaksanakan dua arahan menggunakan transaksi, tetapi salah satu daripadanya gagal
P粉030479054
P粉030479054 2023-09-13 17:55:41
0
1
686

Ralat penerangan

Saya menggunakan senarai redis untuk membuat pengehad dan ia berfungsi seperti yang dijangkakan pada kebanyakan masa, tetapi baru-baru ini saya mendapati bahawa terdapat beberapa kunci yang tidak mempunyai masa tamat tempoh. Sebaik-baiknya saya akan "menolak" nilai ke dalam senarai dan menetapkan masa tamat dalam transaksi dan saya juga akan menggunakan "jam tangan" sebelum transaksi bermula.

Muncul semula

Pepijat ini tidak membiak dalam persekitaran setempat saya, walaupun saya menggunakan jmeter untuk membatch permintaan API berkaitan, seperti 500 permintaan dalam 1 saat

Versi:

Ramalan: v2.1.2 PHP 7.4 Pelayan Redis 5.0.10

Contoh Kod

$redisClient->watch($key);
$current = $redisClient->llen($key);

// Transaction start
$tx = $redisClient->transaction();
if ($current >= $limitNum) {
    $redisClient->unwatch();
    return false;
} else {
  
    if ($redisClient->exists($key)) {
        $tx->rpush($key, $now);

        try {
             $replies = $tx->execute();
             return true;
        } catch (\Exception $e) {
            return false;
        }
    } else {
        // Using transaction to let rpush and expire to be an atomic operation
        $tx->rpush($key, $now);
        $tx->expire($key, $expiryTime);

        try {
             $replies = $tx->execute();
             return true;
        } catch (\Exception $e) {
            return false;
        }
    }
}

Lain-lain

Ini adalah operasi yang dijangkakan dalam pelayan Redis tempatan saya

Urus niaga Redis bersifat atom. Atom bermakna sama ada semua arahan diproses atau tiada arahan diproses. Jadi dalam kes saya kunci harus mempunyai tarikh luput.

P粉030479054
P粉030479054

membalas semua(1)
P粉113938880

Urus niaga Redis bukanlah transaksi atom sebegitu. Mereka adalah atom kerana tiada proses lain boleh mengakses ruang utama semasa urus niaga dalam arahan sedang dilaksanakan. Jika arahan dalam urus niaga gagal, arahan berikutnya akan dilaksanakan dan tidak akan ditarik balik.

Sebagai contoh, mari kita laksanakan transaksi yang mengandungi arahan yang salah:

127.0.0.1:6379> exists mylist
(integer) 0
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> multi
OK
127.0.0.1:6379> rpop mylist
QUEUED
127.0.0.1:6379> sadd mylist d
QUEUED
127.0.0.1:6379> expire mylist 300
QUEUED
127.0.0.1:6379> exec
1) "a"
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 1
127.0.0.1:6379> ttl mylist
(integer) 297

Di sini kami menyemak sama ada senarai itu wujud dan menambah beberapa item awal padanya. Kemudian, dalam urus niaga, kami mengeluarkan item daripada senarai dan tersilap cuba menambah item baharu memikirkan kunci mylist 拥有一个集合,然后设置键 mylist。第一个和第三个命令成功,最后,mylist 设置了生存时间。第二个命令失败。为此,Redis 中没有内置回滚功能 - 您的应用程序需要通过 watch perintah menggunakan penguncian optimistik... Ini adalah untuk mengesan perubahan oleh proses lain sebelum transaksi anda mendapat apa yang transaksi anda inginkan Kunci yang diubah mempunyai akses eksklusif ke pelayan. Ia bukan mekanisme rollback.

Butiran: https://redis.io/docs/interact/transactions/

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan