redis官方對于lua腳本的解釋:Redis使用同一個Lua解釋器來執行所有命令,同時,Redis保證以一種原子性的方式來執行腳本:當lua腳本在執行的時候,不會有其他腳本和命令同時執行,這種語義類似于 MULTI/EXEC。從別的客戶端的視角來看,一個lua腳本要么不可見,要么已經執行完。
然而這也意味著,執行一個較慢的lua腳本是不建議的,由于腳本的開銷非常低,構造一個快速執行的腳本并非難事。但是你要注意到,當你正在執行一個比較慢的腳本時,所以其他的客戶端都無法執行命令。
所以我們總結一下: Lua腳本可以保證原子性,因為Redis會將Lua腳本封裝成一個單獨的事務,而這個單獨的事務會在Redis客戶端運行時,由Redis服務器自行處理并完成整個事務,如果在這個進程中有其他客戶端請求的時候。Redis將會把它暫存起來,等到 Lua 腳本處理完畢后,才會再把被暫存的請求恢復。
這樣就可以保證整個腳本是作為一個整體執行的,中間不會被其他命令插入。但是,如果命令執行過程中命令產生錯誤,事務是不會回滾的,將會影響后續命令的執行.
也就是說,Redis保證以原子方式執行Lua腳本,但是不保證腳本中所有操作要么都執行或者都回滾。
而Redis是支持事務的,而Redis事務主要目的是保證多個命令執行的原子性,即要在一個原子操作中執行,不會被打斷
需要注意的是,Redis的事務是不支持回滾的,如果事務執行過程中發生錯誤,Redis會繼續執行剩余的命令而不是回滾整個事務。
那么為什么Redis不支持事務回滾呢?
按照redis官方解釋是說:
- Redis 事務的執行時,錯誤通常都是編程錯誤造成的,這種錯誤通常只會出現在開發環境中,而很少會在實際的生產環境中出現,所以他認為沒有必要為 Redis 開發事務回滾功能;
- 不支持事務回滾是因為這種復雜的功能和 Redis 追求的簡單高效的設計主旨不符合
參考鏈接:https://redis.io/commands/eval/