redis事務和Jedis
阿新 • • 發佈:2020-08-19
事務
Redis 事務本質:一組命令的集合! 一個事務中的所有命令都會被序列化,在事務執行過程的中,會按 照順序執行!
一次性、順序性、排他性!執行一些列的命令!
------ 佇列 set set set 執行------
Redis事務沒有沒有隔離級別的概念!
所有的命令在事務中,並沒有直接被執行!只有發起執行命令的時候才會執行!Exec
Redis單條命令是保證子性的,但是事務不保證原子性!
redis的事務:
- 開啟事務(multi)
- 命令入隊(......)
- 執行事務(exec)
正常執行事務!
127.0.0.1:6379> multi # 開啟事務 OK # 命令入隊 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> get k2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> exec # 執行事務 1) OK 2) OK 3) "v2" 4) OK
放棄事務!
127.0.0.1:6379> multi # 開啟事務
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> DISCARD # 取消事務
OK
127.0.0.1:6379> get k4 # 事務佇列中命令都不會被執行!
(nil)
編譯型異常(程式碼有問題! 命令有錯!),事務中所有的命令都不會被執行!
127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> getset k3 # 錯誤的命令 (error) ERR wrong number of arguments for 'getset' command 127.0.0.1:6379> set k4 v4 QUEUED 127.0.0.1:6379> set k5 v5 QUEUED 127.0.0.1:6379> exec # 執行事務報錯! (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k5 # 所有的命令都不會被執行! (nil)
執行時異常(1/0), 如果事務佇列中存在語法性,那麼執行命令的時候,其他命令是可以正常執行 的,錯誤命令丟擲異常!
127.0.0.1:6379> set k1 "v1" OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> incr k1 # 會執行的時候失敗! QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k3 QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range # 雖然第一條命令報錯了,但是依舊正常執行成功了! 2) OK 3) OK 4) "v3" 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> get k3 "v3"
監控! Watch (面試常問!)
悲觀鎖:
- 很悲觀,認為什麼時候都會出問題,無論做什麼都會加鎖!
樂觀鎖:
- 很樂觀,認為什麼時候都不會出問題,所以不會上鎖! 更新資料的時候去判斷一下,在此期間是否 有人修改過這個資料,
- 獲取version
- 更新的時候比較 version
Redis監視測試
正常執行成功!
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money # 監視 money 物件
OK
127.0.0.1:6379> multi # 事務正常結束,資料期間沒有發生變動,這個時候就正常執行成功!
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
測試多執行緒修改值 , 使用watch 可以當做redis的樂觀鎖操作!
127.0.0.1:6379> watch money # 監視 money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec # 執行之前,另外一個執行緒,修改了我們的值,這個時候,就會導致事務執行失敗!
(nil)
如果修改失敗,獲取最新的值就好
Jedis
什麼是Jedis
- Jedis 是 Redis 官方推薦的 java連線開發工具! 使用Java 操作Redis 中介軟體!如果你要使用 java操作redis,那麼一定要對Jedis 十分的熟悉!
測試
- 匯入對應的依賴
<!--匯入jedis的包-->
<dependencies>
<!--jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
</dependencies>
-
編碼測試:
- 連線資料庫
- 操作命令
- 斷開連線!
package com.maple; import redis.clients.jedis.Jedis; public class TestPing { public static void main(String[] args){ // 1、 new Jedis 物件即可 Jedis jedis = new Jedis("127.0.0.1",6379); // jedis 所有的命令就是我們之前學習的所有指令! System.out.println(jedis.ping()); } }
輸出:
PONG
name:楓葉age:18
常用的API
-
String
-
List
-
Set
-
Hash
-
Zset
所有的api命令,就是我們對應的上面學習的指令,一個都沒有變化!
事務
public class TestTX {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
jsonObject.put("hello","world");
jsonObject.put("name","kuangshen");
// 開啟事務
Transaction multi = jedis.multi();
String result = jsonObject.toJSONString();
// jedis.watch(result)
try {
multi.set("user1",result);
multi.set("user2",result);
int i = 1/0 ; // 程式碼丟擲異常事務,執行失敗!
multi.exec(); // 執行事務!
} catch (Exception e) {
multi.discard(); // 放棄事務
e.printStackTrace();
} finally {
System.out.println(jedis.get("user1"));
System.out.println(jedis.get("user2"));
jedis.close(); // 關閉連線
}
}
}