日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis-11使用 watch 命令监控事务

發(fā)布時(shí)間:2025/3/21 数据库 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis-11使用 watch 命令监控事务 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 概述
  • Redis watch流程
    • ABA問題
  • 使用watch成功提交的事務(wù)的案例
  • 使用watch回滾的事務(wù)的案例

概述

在 Redis 中使用 watch 命令可以決定事務(wù)是執(zhí)行還是回滾。

一般而言,可以在 multi 命令之前使用 watch 命令監(jiān)控某些鍵值對(duì),然后使用 multi 命令開啟事務(wù),執(zhí)行各類對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的命令,這個(gè)時(shí)候這些命令就會(huì)進(jìn)入隊(duì)列。

當(dāng) Redis 使用 exec 命令執(zhí)行事務(wù)的時(shí)候,它首先會(huì)去比對(duì)被 watch 命令所監(jiān)控的鍵值對(duì),

  • 如果沒有發(fā)生變化,那么它會(huì)執(zhí)行事務(wù)隊(duì)列中的命令,提交事務(wù);
  • 如果發(fā)生變化,那么它不會(huì)執(zhí)行任何事務(wù)中的命令,而去事務(wù)回滾。

無論事務(wù)是否回滾 , Redis 都會(huì)去取消執(zhí)行事務(wù)前的 watch 命令


Redis watch流程

流程如下:

Redis 參考了多線程中使用的 CAS (比較與交換, Compare And Swap ) 去執(zhí)行的。在
數(shù)據(jù)高并發(fā)環(huán)境的操作中,我們把這樣的一個(gè)機(jī)制稱為樂觀鎖.

ABA問題

先簡要論述其操作的過程:

當(dāng)一條線程去執(zhí)行某些業(yè)務(wù)邏輯,但是這些業(yè)務(wù)務(wù)邏輯操作的數(shù)據(jù)可能被其他線程共享了,這樣會(huì)引發(fā)多線程中數(shù)據(jù)不一致的情況。為了克服這個(gè)問題,首先,在線程開始時(shí)讀取這些多線程共享的數(shù)據(jù),并將其保存到當(dāng)前進(jìn)程的副本中,我們稱為舊值( old value), watch 命令就是這樣的一個(gè)功能 。

然后,開啟線程業(yè)務(wù)邏輯,由 multi 命令提供這一功能。在執(zhí)行更新前,比較當(dāng)前線程副本保存的舊值和當(dāng)前線程共享的值是否一致,如果不一致,那么該數(shù)據(jù)己經(jīng)被其他線程操作過,此次更新失敗。為了保持一致,線程就不去更新任何值,而將事務(wù)回滾:否則就認(rèn)為它沒有被其他線程操作過,執(zhí)行對(duì)應(yīng)的業(yè)務(wù)邏輯, exec 命令就是執(zhí)行“類似”這樣的一個(gè)功能 。

注意,“類似”這個(gè)字眼,因?yàn)椴煌耆?#xff0c;原因是 CAS 原理會(huì)產(chǎn)生 ABA 問題。所謂ABA 問題來自于 CAS 原理的一個(gè)設(shè)計(jì)缺陷,它可能引發(fā) ABA 問題

在處理復(fù)雜運(yùn)算的時(shí)候,被線程 2 修改的 X 的值有可能導(dǎo)致線程1的運(yùn)算出錯(cuò),而最后線程 2 將 X 的值修改為原來的舊值 A,那么到了線程 1運(yùn)算結(jié)束的時(shí)間順序 T6,它將j檢測 X 的值是否發(fā)生變化,就會(huì)拿舊值 A 和 當(dāng)前的 X 的值 A 比對(duì) , 結(jié)果是一致的, 于是提交事務(wù),然后在復(fù)雜計(jì)算的過程中 X 被線程 2 修改過了,這會(huì)導(dǎo)致線程1的運(yùn)算出錯(cuò)。

在這個(gè)過程中,對(duì)于線程 2 而言 , X 的值的變化為 A->B->A,所以 CAS 原理的這個(gè)設(shè)計(jì)缺陷被形象地稱為“ABA 問題”。

僅僅記錄一個(gè)舊值去比較是不足夠的,還要通過其他方法避免 ABA 問題。常見的方法
如 Hibernate 對(duì)緩存的持久對(duì)象( PO )加入字段段 version 值,當(dāng)每次操作一次該 PO,則version=version+ 1 , 這樣采用 CAS 原理探測 version 宇段 , 就能在多線程的環(huán)境中,排除ABA 問題,從而保證數(shù)據(jù)的一致性。

Redis 在執(zhí)行事務(wù)的過程中 , 并不會(huì)阻塞其他連接的并發(fā),而只是通過 比較 watch 監(jiān)控的鍵值對(duì)去保證數(shù)據(jù)的一致性 , 所 以 Redis 多個(gè)事務(wù)完全可 以在非阻塞的多線程環(huán)境中井發(fā)執(zhí)行,而且 Redis 的機(jī)制是不會(huì)產(chǎn)生 ABA 問題的, 這樣就有利于在保證數(shù)據(jù)一致的基礎(chǔ)上 , 提高高并發(fā)系統(tǒng)的數(shù)據(jù)讀/寫性能。


使用watch成功提交的事務(wù)的案例

時(shí)刻客戶端說明
T1set key1 value1初始化 key1
T2watch key1監(jiān)控 key1 的健值對(duì)
T3multi開啟事務(wù)
T4set key2 value2設(shè)置 key2 的值
T5exec提交事務(wù), Redis會(huì)在這個(gè)時(shí)間點(diǎn)檢測 key1 的值在 T2 時(shí)刻后,有沒有被其他命令修改泣,如果沒有 , 則提交事務(wù)去執(zhí)行
127.0.0.1:6379> FLUSHDB OK 127.0.0.1:6379> SET key1 value1 OK 127.0.0.1:6379> WATCH key1 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET key2 value2 QUEUED 127.0.0.1:6379> EXEC 1) OK 127.0.0.1:6379>

這里我們使用了 watch 命令設(shè)置了 一個(gè) key1 的監(jiān)控 , 然后開啟事務(wù)設(shè)置 key2 , 直至exec 命令去執(zhí)行事務(wù). 如果在當(dāng)前會(huì)話中修改key1的值,也是可以成功的。


使用watch回滾的事務(wù)的案例

時(shí)刻客戶端1客戶端2說明
T1set key1 value1客戶端 1 :返回 OK
T2watch key1客戶端 1 :監(jiān)控 key1
T3multi客戶端 1: 開啟事務(wù)
T4set key2 value2客戶端1 : 事務(wù)命令入列
T5set key1 val1客戶端 2:修改 key1的值
T6exec客戶端 1:執(zhí)行事務(wù),但是事務(wù)會(huì)先檢查在 T2 時(shí)刻被監(jiān)控的 key1 是否被其他命令修改過。因?yàn)榭蛻舸?2 修改過,所以它會(huì)回滾事務(wù),事實(shí)上如果客戶端執(zhí)行的是 set key1 value1 命令,它也會(huì)認(rèn)為 key1 被修改過,然后返回( nil) ,所以是不會(huì)產(chǎn)生 ABA 問題的

客戶端一

127.0.0.1:6379> FLUSHDB OK 127.0.0.1:6379> 127.0.0.1:6379> SET key1 value1 OK 127.0.0.1:6379> WATCH key1 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set key2 value2 QUEUED# 在這一步暫停下,打開第二個(gè)客戶端去修改key1的值,然后再exec 127.0.0.1:6379> exec (nil) 127.0.0.1:6379>

客戶端二:

然后回到客戶端1 執(zhí)行exec

注意 T2 和 T6 時(shí)刻命令的說明,數(shù)據(jù)已經(jīng)被回滾了,并沒有執(zhí)行事務(wù)。

總結(jié)

以上是生活随笔為你收集整理的Redis-11使用 watch 命令监控事务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。