NoSql-Redis事務
前面介紹了 Redis的 基本操作 現在來介紹一些面試 比較容易問道的 東西
Redis事務的本質:說白了就是,一組命令的集合! 一個事務中的所有命令都會被序列化,在事務執行過程中按照順序執行!
特點:
- 一次性
- 順序性
- 排他性
執行一些列的命令 :------ 佇列 set set set 執行------
- Redis事務沒有隔離級別的概念!
- 所有的命令在事務中,並沒有直接被執行【和函式類似,你寫了定義,沒有呼叫同樣的道理】,只有發起執行命令的時候才會被執行! Exec
-
事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。
-
事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。
EXEC 命令負責觸發並執行事務中的所有命令:【類似與回撥函式機制】
當使用 AOF 方式【後面講解】做持久化的時候, Redis 會使用單個 write(2) 命令將事務寫入到磁碟中。
然而,如果 Redis 伺服器因為某些原因被管理員殺死,或者遇上某種硬體故障,那麼可能只有部分事務命令會被成功寫入到磁碟中。如果 Redis 在重新啟動時發現 AOF 檔案出了這樣的問題,那麼它會退出,並彙報一個錯誤。使用redis-check-aof
程式可以修復這一問題:它會移除 AOF 檔案中不完整事務的資訊,確保伺服器可以順利啟動。
為什麼 Redis 不支援回滾(roll back)
如果你有使用關係式資料庫的經驗, 那麼 “Redis 在事務失敗時不進行回滾【Orcal有回滾:回bai滾指的是程式或資料du處理錯誤,將程式或資料恢復到上一次正確狀態的行為。回滾包括程式回滾和資料回滾等型別。說白了就是類似撤消操作】,而是繼續執行餘下的命令”這種做法可能會讓你覺得有點奇怪。
以下是這種做法的優點:
- Redis 命令只會因為錯誤的語法而失敗(並且這些問題不能在入隊時發現),或是命令用在了錯誤型別的鍵上面:這也就是說,從實用性的角度來說,失敗的命令是由程式設計錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生產環境中。
- 因為不需要對回滾進行支援,所以 Redis 的內部可以保持簡單且快速。
有種觀點認為 Redis 處理事務的做法會產生 bug , 然而需要注意的是, 在通常情況下, 回滾並不能解決程式設計錯誤帶來的問題。 舉個例子, 如果你本來想通過 INCR 命令將鍵的值加上 1 , 卻不小心加上了 2 , 又或者對錯誤型別的鍵執行了 INCR , 回滾是沒有辦法處理這些情況的。
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> set k3 v3
- QUEUED
- 127.0.0.1:6379> GET k2
- QUEUED
- 127.0.0.1:6379> exec
- 1) OK
- 2) OK
- 3) OK
- 4) "v2"
-----------------------------------------------------------------------------------------------------------------------------
# 放棄事務 事務中的所有命令都不會執行
- 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> DISCARD
- OK
- 127.0.0.1:6379> get k3
- (nil)
- 127.0.0.1:6379> get k2
- (nil)
- 127.0.0.1:6379> get k1
- (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 k2 v4
- QUEUED
- 127.0.0.1:6379> GETSET k2
- (error) ERR wrong number of arguments for 'getset' command
- 127.0.0.1:6379>
- 127.0.0.1:6379> get k3
- QUEUED
- 127.0.0.1:6379> EXEC
- (error) EXECABORT Transaction discarded because of previous errors.
- 127.0.0.1:6379>
- 127.0.0.1:6379> get k1
- (nil)
-----------------------------------------------------------------------------------------------------------------------------
- 127.0.0.1:6379> MULTI
- OK
- 127.0.0.1:6379> set k1 "libero"
- QUEUED
- 127.0.0.1:6379> set k2 v2
- QUEUED
- 127.0.0.1:6379> set k3 v3
- QUEUED
- 127.0.0.1:6379> INCRBY k1 5 // 字串 + - 出錯
- QUEUED
- 127.0.0.1:6379> GET k1
- QUEUED
- 127.0.0.1:6379> GET k2
- QUEUED
- 127.0.0.1:6379> exec
- 1) OK
- 2) OK
- 3) OK
- 4) (error) ERR value is not an integer or out of range
- 5) "libero"
- 6) "v2"
-----------------------------------------------------------------------------------------------------------------------------
監控! watch(面試常問)
不會吧 不會吧 Redis 也有Sql的 悲觀鎖 樂觀鎖 ?是的 錯了 ,這裡只是用 watch達到樂觀鎖的目的
先來介紹一下 悲觀,樂觀鎖
悲觀鎖:很悲觀,認為什麼時候都會出問題,無論做什麼都會加鎖!【顧名思義】雖說保證了安全性但是效率很低,傳統的關係型資料庫 有很多這樣的列子:比如 行鎖,表鎖,讀鎖,寫鎖等,都是在操作前加上鎖,防止多人修改同一條資料。這樣的話就成功提高了資料的一致性,降低了併發性。
樂觀鎖: 很樂觀,認為什麼時候都不會出現問題,所以不會上鎖!更新資料的時候取判斷一下,在此期間是否有人修改過
這個資料。通過獲取version,更新的時候比較version【通過watch達到目的】樂觀鎖策略:提交版本必須大於記錄當前版本才能更新資料
這裡就是 另一個 client 修改了 當前的 版本,處理事務這個client的版本就是watch的時候獲取的版本,但之後在執行Exec之前,我們用另一個client修改了當前的版本 ,讓money這個version > 處理事務的client。所以按照執行策略,這裡的事務執行是失敗的。
- 27.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> INCRBY money -20
- QUEUED
- 127.0.0.1:6379> INCRBY out 20
- 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> INCRBY money -20
- QUEUED
- 127.0.0.1:6379> INCRBY out 20
- QUEUED
- 127.0.0.1:6379> exec
- 1) (integer) 180
- 2) (integer) 20
相關文章
- 十、Redis事務、事務鎖Redis
- 分散式事務之Spring事務與JMS事務(二)分散式Spring
- 什麼是事務、事務特性、事務隔離級別、spring事務傳播特性?Spring
- MySQL事務(一)認識事務MySql
- 事務
- 分散式事務之資料庫事務與JDBC事務實現(一)分散式資料庫JDBC
- Spring事務專題(三)事務的基本概念,Mysql事務處理原理SpringMySql
- redis事務Redis
- mysql事務MySql
- Redis 事務Redis
- SQL事務SQL
- 05事務
- 01 事務
- JAVA事務Java
- oracle事務Oracle
- spring事務Spring
- Spring 事務Spring
- MySQL 事務MySql
- PostgreSQL:事務SQL
- Spring的事務管理(二)宣告式事務管理Spring
- 資料庫事務與 MySQL 事務總結資料庫MySql
- 本地事務和分散式事務的區別分散式
- 分散式事務(一)—分散式事務的概念分散式
- 事務使用中如何避免誤用分散式事務分散式
- 資料庫事務以及事務的四個特性資料庫
- 事務與MVCCMVC
- Spring 事務管理Spring
- redis-事務Redis
- DAPPER 事務 TRANSACTIONAPP
- 事務的使用
- indexedDB transaction 事務Index
- 7. 事務
- MySQL 事務操作MySql
- MySQL--->事務MySql
- 事務隔離
- MySQL 三 事務MySql
- 事務及索引索引
- MySQL--事務MySql