文章目錄
- Redis中的原子性
- Redis的事物和MySQL事務的區別
- Redis實現事務
- 什么場景下,會使用事務?
- Redis事務相關命令
- watch命令的實現原理
- 總結
Redis中的原子性
Redis的原子性不同于MySQL的原子性。
Redis的事物和MySQL事務的區別
但是注意體會Redis的事務和MySQL事務的區別:
? 弱化的原?性:redis沒有"回滾機制".只能做到這些操作"批量執?".不能做到"?個失敗就恢復到
初始狀態".
? 不保證?致性:不涉及"約束".也沒有回滾.MySQL的?致性體現的是運?事務前和運?后,結果都
是合理有效的,不會出現中間?法狀態.
? 不需要隔離性:也沒有隔離級別,因為不會并發執?事務(redis單線程處理請求).
? 不需要持久性:是保存在內存的.是否開啟持久化,是redis-server??的事情,和事務?關.
Redis實現事務
Redis中為了實現事務,引入了一個隊列。
如果一個客戶端開啟了事務功能,該客戶端就會維持一個隊列,每次用戶輸入的命令,都會先進入該隊列,然后等待用戶輸入執行事務的命令后,該隊列中的命令才一次被執行,且執行完才會處理其他客戶端的命令。
什么場景下,會使用事務?
鐵路12306搶票的例子:
總結:redis中事務比MySQL的事務弱化了很多。
Redis事務本質上是在服務器上搞了?個"事務隊列".每次客?端在事務中進??個操作,都會把命令先
發給服務器,放到"事務隊列"中(但是并不會?即執?)。?是會在真正收到EXEC命令之后,才真正執?隊列中的所有操作.
因此,Redis的事務的功能相?于MySQL來說,是弱化很多的.只能保證事務中的這?個操是"連續的",不會被別的客?端"加塞",僅此?已。
Redis事務相關命令
multi:開啟事務
開啟事務后,接下來的所有命令都會放入事務隊列中,不執行。
exec:執行事務 : 此時才真正執行隊列的命令
discard:放棄當前事務,也就是把當前事務隊列的命令都丟掉然后退出事務模式。
watch命令:watch監控某個key是否在一個事務執行前發生改了改變。
舉個watch命令的例子:
但實際上,最后結果key是222。這對客戶端2就不公平了,為什么我set key 333了,結果確是222?
就導致數據不一致的問題。
剛才的場景中,就可以使用watch命令來監控key,看看這個key在事務的multi和exec之間,set key之后,是否在外部被其他客戶端修改了。
此時,exec后,在真正執行事務隊列的命令時,發現key外部有修改,于是真正執行key 222的時候就出現了(nil),相當于只要發現我watch的key在事務外部有變化,該事務隊列就被丟棄了。
watch命令的實現原理
watch的實現,類似一個”樂觀鎖“
先解釋下樂觀鎖和悲觀鎖:
樂觀鎖:加鎖之前有一個心里預期,預期接下來的鎖沖突的概率較低。
悲觀鎖:加鎖之前有一個心里預期,預期接下來的鎖沖突的概率較高。
持有上面兩種心態后,對鎖沖突的操作,也有不同。
對于持有“樂觀“心態的:加鎖的代碼可能少,成本低。
對于持有“悲觀“心態的:加鎖的代碼可能多,成本高。
redis的watch,是基于“版本號”這種機制,實現的樂觀鎖。
總結