Redis事務處理的使用操作方法
一、簡介
Redis采用瞭樂觀鎖方式進行事務控制,它使用watch命令監視給定的key,當exec(提交事務)的時候,如果監視的key從調用watch後發生過變化,則整個事務會失敗。也可以調用watch多次監視多個key。註意watch的key是對整個連接有效的,如果連接斷開,監視和事務都會被自動清除。當然exec,discard,unwatch命令都會清除連接中的所有監視。
Redis保證一個事務中的所有命令要麼都執行,要麼都不執行(原子性)。如果在發送EXEC命令前客戶端斷線瞭,則Redis會清空事務隊列,事務中的所有命令都不會執行。而一旦客戶端發送瞭EXEC命令,所有的命令就都會被執行,即使此後客戶端斷線也沒關系,因為Redis中已經記錄瞭所有要執行的命令。
常用指令:
- multi 開啟事務
- exec 提交事務
- discard 取消事務
- watch 監控,如果監控的值發生變化,則提交事務時會失敗
- unwatch 去掉監控
二、模擬使用
模擬轉賬操作
開啟事務後所有操作都會進入到一個隊列中,提交時一起執行
模擬取消事務
redis事務太簡單,沒有回滾,而隻有取消。
當隊列中有語句出現錯誤時,事務會自動取消
樂觀鎖使用演示
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,期間該數據可以隨便被其他人讀取,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。
版本號機制是樂觀鎖最常用的方式,就是在表中增加一個版本號的字段,更新前先查一遍獲取版本號,再作為更新語句的where條件進行更新,如果數據在獲取版本號之後,在更新之前已經改變瞭,那就會更新失敗,因為最後更新瞭0條數據,java後臺拿到更新數如果為0,則說明更新失敗,出現瞭並發問題,然後做具體的處理。
1.添加測試數據語句
開啟監控,開啟事務,執行語句
2.另起一個redis對數據進行修改
3.返回第一個數據庫提交事務
這裡我們可以看到執行事務失敗。a變成瞭666
三、樂觀鎖秒殺搶票練習
/*基於reids實現一個簡單的多線程搶票操作 * 重點延時樂觀鎖的應用*/ public class SecondsKillDemo02 { //定義搶票邏輯 public static void KillTicket() { //1.連接 Jedis jedis = JedisDataSource.getConnection(); //2.監控reids中指定的key String a = jedis.get("a"); if (a == null || Integer.valueOf(a) == 0) throw new RuntimeException("沒票瞭"); jedis.watch("a", "b"); //3.開啟事務執行業務 Transaction multi = jedis.multi(); try { multi.decr("a"); multi.incrBy("b", 100); //4.提交事務 multi.discard(); System.out.println("ok"); } catch (Exception e) { multi.exec(); } finally { //5.取消監控 jedis.unwatch(); //6.釋放 jedis.close(); } } public static void main(String[] args) { //1.定義初始數據 Jedis jedis = JedisDataSource.getConnection(); jedis.set("a", "1"); jedis.set("b", "0"); //2.創建多個線程,在線程中執行搶票 Thread t1 = new Thread(new Runnable() { @Override public void run() { KillTicket(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { KillTicket(); } }); t1.start(); t2.start(); } }
到此這篇關於Redis事務處理的文章就介紹到這瞭,更多相關Redis事務處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!