Redis 基本事務操作和實現樂觀鎖

2021-10-10 18:36:35 字數 4271 閱讀 1246

實現樂觀鎖

事務的本質就是一組命令的集合。乙個事務中的所有命令都會被序列化,在事務執行過程的中,會按照順序執行。

redis事務三個重要的保證

乙個事務從開始到執行會經歷以下三個階段:

單個 redis 命令的執行是原子性的,但 redis 沒有在事務上增加任何維持原子性的機制,所以 redis 事務的執行並不是原子性的。 (原子性:要麼事務中命令都成功,要麼都失敗。redis事務並不滿足)

redis事務操作的一些命令

序號命令描述1

discard

取消事務,放棄執行事務塊內的所有命令。

2exec

執行所有事務塊內的命令。

3multi

標記乙個事務塊的開始。

4unwatch

取消 watch 命令對所有 key 的監視。

5watch key [key …]

監視乙個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。

正常執行事務的流程:

# 開啟事務

127.0.0.1:6379> multi

ok#命令入隊

127.0.0.1:6379>

set key1 value1

queued

127.0.0.1:6379>

set key2 value2

queued

127.0.0.1:6379>

set key3 value3

queued

127.0.0.1:6379> get key2

queued

#執行事務

127.0.0.1:6379>

exec

1) ok

2) ok

3) ok

4)"value2"

開始事務後,一些命令已入佇列,但是我們不想執行了,這時我們可以放棄這個事務,不執行佇列中的命令。

#開啟事務

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

ok#查詢取消事務中命令是否執行

127.0.0.1:6379> get k2

(nil)

127.0.0.1:6379>

有錯誤的命令,事務中的所有命令都不會被執行

# 開啟事務

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 v3

(error) err wrong number of arguments for

'getset'

command

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 k2

(nil)

127.0.0.1:6379>

命令正常,但有語法錯誤,語法錯誤的命令丟擲異常,其他命令正常執行

#開啟事務

127.0.0.1:6379> multi

ok #命令入隊

127.0.0.1:6379>

set k1 a

queued

#語法錯誤的命令

127.0.0.1:6379>

set k2 a b

queued

127.0.0.1:6379>

set k3 c

queued

#執行事務 ==》語法錯誤的命令報錯,其他成功執行

127.0.0.1:6379>

exec

1) ok

2)(error) err syntax error

3) ok

悲觀鎖(pessimistic lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖(optimistic lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

redis watch命令用於監視乙個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷,這就是redis樂觀鎖的乙個操作。

實現流程:

watch命令監視乙個key的value。

開啟事務,命令入隊,命令中包括修改監視key的value。

執行事務前,會拿事務前監視的value和現在執行修改前的的value進行比較,也就是看一下執行事務之前,value是否被修改,比較不相等,事務執行失敗,反之成功。

失敗後怎麼處理?首先unwatch放棄監視之前的key,接下來執行你想要的操作命令。

操作:開啟兩個終端:

(1)開啟另乙個終端2

ocalhost bin]

# redis-cli -p 6379

127.0.0.1:6379>

(2)在終端1中設定有乙個1000元的money,0元的支出output

127.0.0.1:6379>

set money 1000

ok127.0.0.1:6379>

set output 0

ok

(3)在終端2開啟監視money

[root@localhost bin]

# redis-cli -p 6379

127.0.0.1:6379>

watch money

ok

(4)在終端1修改money

127.0.0.1:6379> decrby money 200

ok127.0.0.1:6379> incrby output 200

ok

(5)在終端2中開啟事務,並最後執行事務,可以看到事務執行失敗

127.0.0.1:6379> multi

ok127.0.0.1:6379> decrby money 500

queued

127.0.0.1:6379> incrby output 500

queued

127.0.0.1:6379>

exec

(nil)

(6)放棄監視後重新監視,執行其他事務

127.0.0.1:6379> unwatch

ok127.0.0.1:6379>

watch money

ok127.0.0.1:6379> multi

ok127.0.0.1:6379> decrby money 300

queued

127.0.0.1:6379> incrby output 300

queued

127.0.0.1:6379>

exec

1)(integer) 500

2)(integer) 500

Redis基本事務操作

redis事務本質 一組命令的集合!乙個事務中的所有命令都會被序列化,在事務直線過程中,會按照順序執行!redis事務沒有隔離級別的概念所有的命令在事務中,並沒有直接被執行!只有發起執行命令的時候才會執行!exec redis單條命令式儲存原子性的,但是事務不保證原子性!redis的事務 開啟事務 ...

Redis的基本事務操作

事務 redis事務本質 一組命令的集合!乙個事務中的所有命令都會被序列化,在事務執行過程中,會按順序執行 一次性 順序性 排他性!執行一系列的命令 佇列 set set set 執行 redis事務沒有隔離級別的概念 所有的命令在事務中,並沒有直接被執行,只有發起執行命令的時候才會執行!exec ...

教程 Hibernate 基本操作和事務

hibernate 一級快取 hibernate 事務操作 hibernate 其他api 查詢 第二類 hibernate的二級快取,其特點如下 一級快取的使用的例子 1 首先根據uid 1查詢,返回物件 2 其次再根據uid 1查詢,返回物件 查詢了兩次uid 1的資料,第一次會傳送sql語句查...