一條龍網(wǎng)站建設(shè)哪家好游戲推廣員是做什么的
Redis 的事務(wù)的本質(zhì)是 一組命令的批處理 。這組命令在執(zhí)行過程中會被順序地、一次性全部執(zhí)行完畢,只要沒有出現(xiàn)語法錯誤,這組命令在執(zhí)行期間是不會被中斷。
當(dāng)事務(wù)中的命令出現(xiàn)語法錯誤時,整個事務(wù)在 exec 執(zhí)行時會被取消。
如果事務(wù)中的命令沒有語法錯誤,但在執(zhí)行過程中出現(xiàn)異常,該異常不會影響其它命令的執(zhí)行。(比如incrby一個字符)
Redis 的事務(wù)僅保證了數(shù)據(jù)的一致性,不具有像 DBMS 一樣的 ACID 特性。? 這組命令中的某些命令的執(zhí)行失敗不會影響其它命令的執(zhí)行,不會引發(fā)回滾。即不具備原子性。? 這組命令通過樂觀鎖機制實現(xiàn)了簡單的隔離性。沒有復(fù)雜的隔離級別。? 這組命令的執(zhí)行結(jié)果是被寫入到內(nèi)存的,是否持久取決于 Redis 的持久化策略,與事務(wù)無關(guān)。
Redis 事務(wù)通過三個命令進行控制。? muti :開啟事務(wù)? exec :執(zhí)行事務(wù)? discard :取消事務(wù)
在并發(fā)場景下可能會出現(xiàn)多個客戶端對同一個數(shù)據(jù)進行修改的情況。
例如:有兩個客戶端 C 左與 C 右, C 左需要申請 40 個資源, C 右需要申請 30 個資源。
它們首先查看了當(dāng)前擁有的資源數(shù)量,即 resources 的值。它們查看到的都是 50 ,都感覺資
源數(shù)量可以滿足自己的需求,于是修改資源數(shù)量,以占有資源。但結(jié)果卻是資源出現(xiàn)了“超
賣”情況。
為了解決這種情況, Redis 事務(wù)通過樂觀鎖機制實現(xiàn)了多線程下的執(zhí)行隔離。
Redis 通過 watch 命令再配合事務(wù)實現(xiàn)了多線程下的執(zhí)行隔離。

?
?
其內(nèi)部的執(zhí)行過程如下: 1) 當(dāng)某一客戶端對 key 執(zhí)行了 watch 后,系統(tǒng)就會為該 key 添加一個 version 樂觀鎖,并初始化 version 。例如初值為 1.0 。2) 此后客戶端 C 左將對該 key 的修改語句寫入到了事務(wù)命令隊列中,雖未執(zhí)行,但其將該key 的 value 值與 version 進行了讀取并保存到了當(dāng)前客戶端緩存。此時讀取并保存的是version 的初值 1.0 。3) 此后客戶端 C 右對該 key 的值進行了修改,這個修改不僅修改了 key 的 value 本身,同時也增加了 version 的值,例如使其 version 變?yōu)榱? 2.0 ,并將該 version 記錄到了該 key信息中。4) 此后客戶端 C 左執(zhí)行 exec ,開始執(zhí)行事務(wù)中的命令。不過,其在執(zhí)行到對該 key 進行修改的命令時,該命令首先對當(dāng)前客戶端緩存中保存的 version 值與當(dāng)前 key 信息中的version 值。如果緩存 version 小于 key 的 version ,則說明客戶端緩存的 key 的 value 已經(jīng)過時,該寫操作如果執(zhí)行可能會破壞數(shù)據(jù)的一致性。所以該寫操作不執(zhí)行。