1. 程式人生 > 實用技巧 >五,redis的事務,樂觀鎖和悲觀鎖

五,redis的事務,樂觀鎖和悲觀鎖

事務是什麼,我認為事務是不成功,便成仁;

事務是訪問並可能操作各種資料項的一個數據庫操作序列,這些操作要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。事務由事務開始與事務結束之間執行的全部資料庫操作組成。

但是在redis中,事務中是不存在原子性的。

一,redis是一群命令的組合,每個命令在一條佇列中,順序執行;

一個事務中所有的命令都會被序列化,在執行任務的時候,順序執行。

二,redis事務沒有隔離級別的概念;

三,redis的三個階段

1)開始事務;

2)命令進入佇列;

3)執行命令。

四,redis的相關命令

1)multi 開啟事務;

2)watch key1 ..... keyn,監視一個或者多個key,如果在事務執行之前,被監視的key被其他命令改動,則事務被打斷。

3)exec:執行所有命令;

4)unwach:取消對所有key的監控;

5)discard:取消事務,放棄事務塊中的所有命令;

五,指令例項

1)事務的基本過程

開啟事務,命令進入序列中,執行命令;

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name laoli
QUEUED
127.0.0.1:6379> set sex boy
QUEUED
127.0.0.1:6379> set age 30
QUEUED
127.0.0.1:6379> keys *
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) OK
4) 1) "score_ch"
2) "sex"
3) "name"
4) "age"

2)在事務中,入隊的命令中其中有一個命令有錯誤,事務中所有的命令是不執行的;

3)在事務中,入隊的命令是存在語法性的錯誤,在執行其他命令時候,其他的命令是可以正常執行的,錯誤的命令會丟擲異常;

六,悲觀鎖和樂觀鎖

在事務中,事務是有原子性的,事務是可以回滾的;

但是在redis中,事務是非原子性的,如何讓事務有回滾的能力,需要藉助wath命令去監控命令去實現。

1)樂觀鎖:開啟事務前,設定對資料的監聽,EXEC時,如果發生資料發生過修改,事務會自動取消(DISCARD)

認為什麼事情,都不會出現問題,都是樂觀的,不會上鎖;

監控money:正常執行;

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 
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

如果在監視的money中,發生了變化,則事務會自動取消

新開一個執行緒,新增讓money變成1000

127.0.0.1:6379> get money
"80"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> 

在開執行緒之前,首先watch money,然後開始事務,然後新開一個執行緒,讓money變成1000,就是執行上面的程式碼;然後money減去10元,out新增10元,exec後,出現nil

127.0.0.1:6379> get money
"80"
127.0.0.1:6379> watch 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)

上面的案例可以看出,樂觀鎖在監控到元素髮生變化是,取消操作;

解決辦法是,放棄監視,重新執行;

127.0.0.1:6379> UNWATCH
OK
127.0.0.1:6379> watch 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
1) (integer) 990
2) (integer) 30

 2)悲觀鎖

認為任何事情,都會出現問題,都是悲觀的,很消耗效能;

我們在sql中使用的for update,應用程式的層面手工實現資料加鎖保護操作