Redis事務(wù)處理的使用操作方法
一、簡介
Redis采用了樂觀鎖方式進行事務(wù)控制,它使用watch命令監(jiān)視給定的key,當exec(提交事務(wù))的時候,如果監(jiān)視的key從調(diào)用watch后發(fā)生過變化,則整個事務(wù)會失敗。也可以調(diào)用watch多次監(jiān)視多個key。注意watch的key是對整個連接有效的,如果連接斷開,監(jiān)視和事務(wù)都會被自動清除。當然exec,discard,unwatch命令都會清除連接中的所有監(jiān)視。
Redis保證一個事務(wù)中的所有命令要么都執(zhí)行,要么都不執(zhí)行(原子性)。如果在發(fā)送EXEC命令前客戶端斷線了,則Redis會清空事務(wù)隊列,事務(wù)中的所有命令都不會執(zhí)行。而一旦客戶端發(fā)送了EXEC命令,所有的命令就都會被執(zhí)行,即使此后客戶端斷線也沒關(guān)系,因為Redis中已經(jīng)記錄了所有要執(zhí)行的命令。
常用指令:
- multi 開啟事務(wù)
- exec 提交事務(wù)
- discard 取消事務(wù)
- watch 監(jiān)控,如果監(jiān)控的值發(fā)生變化,則提交事務(wù)時會失敗
- unwatch 去掉監(jiān)控
二、模擬使用
模擬轉(zhuǎn)賬操作

開啟事務(wù)后所有操作都會進入到一個隊列中,提交時一起執(zhí)行
模擬取消事務(wù)
redis事務(wù)太簡單,沒有回滾,而只有取消。

當隊列中有語句出現(xiàn)錯誤時,事務(wù)會自動取消

樂觀鎖使用演示
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數(shù)據(jù)的時候都認為別人不會修改,所以不會上鎖,期間該數(shù)據(jù)可以隨便被其他人讀取,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),可以使用版本號等機制。
版本號機制是樂觀鎖最常用的方式,就是在表中增加一個版本號的字段,更新前先查一遍獲取版本號,再作為更新語句的where條件進行更新,如果數(shù)據(jù)在獲取版本號之后,在更新之前已經(jīng)改變了,那就會更新失敗,因為最后更新了0條數(shù)據(jù),java后臺拿到更新數(shù)如果為0,則說明更新失敗,出現(xiàn)了并發(fā)問題,然后做具體的處理。
1.添加測試數(shù)據(jù)語句
開啟監(jiān)控,開啟事務(wù),執(zhí)行語句
2.另起一個redis對數(shù)據(jù)進行修改

3.返回第一個數(shù)據(jù)庫提交事務(wù)
這里我們可以看到執(zhí)行事務(wù)失敗。a變成了666

三、樂觀鎖秒殺搶票練習(xí)
/*基于reids實現(xiàn)一個簡單的多線程搶票操作
* 重點延時樂觀鎖的應(yīng)用*/
public class SecondsKillDemo02 {
//定義搶票邏輯
public static void KillTicket() {
//1.連接
Jedis jedis = JedisDataSource.getConnection();
//2.監(jiān)控reids中指定的key
String a = jedis.get("a");
if (a == null || Integer.valueOf(a) == 0)
throw new RuntimeException("沒票了");
jedis.watch("a", "b");
//3.開啟事務(wù)執(zhí)行業(yè)務(wù)
Transaction multi = jedis.multi();
try {
multi.decr("a");
multi.incrBy("b", 100);
//4.提交事務(wù)
multi.discard();
System.out.println("ok");
} catch (Exception e) {
multi.exec();
} finally {
//5.取消監(jiān)控
jedis.unwatch();
//6.釋放
jedis.close();
}
}
public static void main(String[] args) {
//1.定義初始數(shù)據(jù)
Jedis jedis = JedisDataSource.getConnection();
jedis.set("a", "1");
jedis.set("b", "0");
//2.創(chuàng)建多個線程,在線程中執(zhí)行搶票
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();
}
}
到此這篇關(guān)于Redis事務(wù)處理的文章就介紹到這了,更多相關(guān)Redis事務(wù)處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
websocket+redis動態(tài)訂閱和動態(tài)取消訂閱的實現(xiàn)示例
本文主要介紹了websocket+redis動態(tài)訂閱和動態(tài)取消訂閱,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Python利用redis限制用戶重復(fù)刷新帶來的數(shù)據(jù)問題
在網(wǎng)站開發(fā)中,我們經(jīng)常會遇到需要控制用戶重復(fù)刷新頁面的情況,本文就來介紹了Python利用redis限制用戶重復(fù)刷新帶來的數(shù)據(jù)問題,感興趣的可以了解一下2024-03-03
Redisson如何解決redis分布式鎖過期時間到了業(yè)務(wù)沒執(zhí)行完問題
這篇文章主要介紹了Redisson如何解決redis分布式鎖過期時間到了業(yè)務(wù)沒執(zhí)行完問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
Redis未授權(quán)訪問配合SSH key文件利用詳解
這篇文章主要給大家介紹了關(guān)于Redis未授權(quán)訪問配合SSH key文件利用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09

