Redis的事務、樂觀鎖和悲觀鎖
一、是什麼
- 可以一次執行多個命令,本質是一組命令的集合。
- 一個事務中的所有命令都會序列化,按照順序地序列化執行而不會被其他命令插入,不許加塞
二、能幹嘛
- 一個佇列中,一次性、順序性、排他性的執行一系列命令
三、怎麼玩
- Redis中開啟事務的命令是:MULTI ,這個命令通常會回覆一個OK【回覆的是OK,但是這個事能不能辦,什麼時候辦,辦不辦的成不知道】,使用者將會一次性的打多個命令,而代替執行,按順序執行,Redis將這些命令入隊,所有的命令將會通過命令:EXEC 來被呼叫執行。
- 如果用命令:DISCARD 表示放棄丟棄,言下之意是放棄本次的批處理操作
常用命令:
- DISCARD:取消事務,放棄執行事務塊內的所有命令
- EXEC:執行所有事務塊內的命令
- MULTI:標記一個事務塊的開始
- UNWATCH:取消 WATCH 命令對所有 key 的監控
- WATCH key [key . . . ]:件事一個(或多個)key,如果在事務執行之前這個(或這些)key被其他命令所改動,那麼事務將被打斷
正常執行:
放棄事務:
全體連坐:【在事務塊中只要有一條命令執行是錯的,那麼整個事務塊就不會執行】
冤頭債主:【如果在事務塊中所有命令都正確,但是結果會產生錯誤,那麼冤有頭債有主,誰錯找誰】
watch監控:
- 悲觀鎖
- 悲觀鎖(Pessimistic Lock),顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,當其他執行緒想要訪問資料時,都需要阻塞掛起。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖、表鎖,讀鎖,寫鎖等,都是在操作之前先上鎖。
- 在Java中,synchronized的思想也是悲觀鎖。
- 樂觀鎖:【衝突檢測和資料更新】
- 樂觀鎖(Optimistic Lock),顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候回判斷一下再次期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量。
- 樂觀鎖策略:提交版本必須大於記錄當前版本才能執行更新
- 一般會使用版本號機制或CAS操作實現:
- version方式:一般是在資料表中加上一個資料版本號version欄位,表示資料被修改的次數,當資料被修改時,version值會加一。當執行緒A要更新資料值時,在讀取資料的同時也會讀取version值,在提交更新時,若剛才讀取到的version值為當前資料庫中的version值相等時才更新,否則重試更新操作,直到更新成功。
核心SQL程式碼:
update table set x=x+1, version=version+1 where id=#{id} and version=#{version};
- CAS(Check And Set【先檢查再動手設定】)
- CAS操作方式:即 compare and set,CAS是樂觀鎖技術,涉及到三個運算元,資料所在的記憶體值,預期值,新值。當需要更新時,判斷當前記憶體值與之前取到的值是否相等,若相等,則用新值更新,若失敗則重試,一般情況下是一個自旋操作,即不斷的重試。
********************************************************************
*無加塞篡改,先監控再開啟 MULTI ,保證兩筆金額變動在同一個事務內*
********************************************************************
- 如下圖:就模擬了一個購物的過程,在買的過程中,別人會給你打錢,當你要完成支付的時候報錯了
- 解決:【使用 UNWATCH 取消對當前 key 的監控,之後再一次進行監控(得到最新的資料),直到成功為止】
注意:
**********************************************
一旦執行了 EXEC,之前加的監控所都會被取消掉*
**********************************************
四、小結
- 通過 WATCH 命令在事務執行之前監控了多個 Keys,倘若在 WATCH 之後有任何 Key 的值發生變化,EXEC 命令執行的事務都將被放棄,同時返回 Nullmulti-bulk 應答以通知呼叫者事務執行失敗
五、三階段
- 開啟:以 MULTI 開始一個事務
- 入隊:將多個命令入隊到事務中,接到這些命令並不會立即執行,而是放到等待執行的事務佇列裡面
- 執行:由 EXEC 命令觸發事務
六、三特性
- 單獨的隔離操作:事務中所有的命令多會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷
- 沒有隔離級別的概念:佇列中的命令沒有提交之前都不會實際的被執行,因為事務提交前任何指令都不會被實際的執行,也就是不存在 “ 事務內的查詢要看到事務裡面的更新,在事務外查詢不能看到 ” 這個是讓人萬分頭痛的問題
- 不保證原子性:Redis 同一個事務中如果有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾
相關文章
- 悲觀鎖和樂觀鎖
- laravel樂觀鎖和悲觀鎖Laravel
- 理解樂觀鎖和悲觀鎖
- MySQL樂觀鎖和悲觀鎖介紹MySql
- mysql悲觀鎖以樂觀鎖MySql
- MySQL鎖(樂觀鎖、悲觀鎖、多粒度鎖)MySql
- SQLServer樂觀鎖定和悲觀鎖定例項SQLServer
- 資料庫中的悲觀鎖和樂觀鎖資料庫
- JPA和Hibernate的樂觀鎖與悲觀鎖
- java-樂觀鎖與悲觀鎖Java
- MybatisPlus - [03] 樂觀鎖&悲觀鎖MyBatis
- Java 中的悲觀鎖和樂觀鎖的實現Java
- Java中的鎖之樂觀鎖與悲觀鎖Java
- 面試必備知識點:悲觀鎖和樂觀鎖的那些事兒面試
- MySQL 悲觀鎖與樂觀鎖的詳解MySql
- 小議“悲觀鎖和樂觀鎖”的原理、場景、示例
- 樂觀鎖和悲觀鎖策略的區別與實現
- 利用MySQL中的樂觀鎖和悲觀鎖實現分散式鎖MySql分散式
- 面試必備之悲觀鎖與樂觀鎖面試
- 面試必備之樂觀鎖與悲觀鎖面試
- Java彌散系列 - 樂觀鎖與悲觀鎖Java
- 樂觀鎖和悲觀鎖在kubernetes中的應用
- SQL SERVER樂觀鎖定和悲觀鎖定使用例項SQLServer
- 【鎖機制】共享鎖、排它鎖、悲觀鎖、樂觀鎖、死鎖等等
- 樂觀鎖與悲觀鎖及應用舉例
- 解鎖你的資料庫:JPA和Hibernate的樂觀鎖與悲觀鎖資料庫
- 悲觀鎖與樂觀鎖的實現(詳情圖解)圖解
- 面試必備的資料庫悲觀鎖與樂觀鎖面試資料庫
- 關於樂觀鎖與悲觀鎖的實際應用
- SSM (十五) 樂觀鎖與悲觀鎖的實際應用SSM
- Java併發程式設計(05):悲觀鎖和樂觀鎖機制Java程式設計
- Spring Boot2+JPA之悲觀鎖和樂觀鎖實戰Spring Boot
- 經典問題之樂觀鎖和悲觀鎖及使用場景
- [轉帖]SQL Server 鎖機制 悲觀鎖 樂觀鎖 實測解析SQLServer
- 深入理解Redis事務、事務異常、樂觀鎖、管道Redis
- 【每日鮮蘑】從資料庫看樂觀鎖、悲觀鎖資料庫
- Laravel 事務中 使用 悲觀鎖 小結Laravel
- Java鎖最全詳解:樂觀鎖/悲觀鎖+公平鎖/非公平鎖+獨享鎖/共享鎖Java