cari

Rumah  >  Soal Jawab  >  teks badan

Predis melaksanakan dua arahan menggunakan transaksi, tetapi salah satu daripadanya gagal

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粉030479054P粉030479054443 hari yang lalu661

membalas semua(1)saya akan balas

  • P粉113938880

    P粉1139388802023-09-14 11:49:51

    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/

    balas
    0
  • Batalbalas