概述
Redis中的事務是一組命令的集合。一個事務中的命令要麼都執行,要麼都不執行。Redis能保證一個事務內的命令依次執行而不被其他命令插入。Redis事務沒有提供類似關係型數據庫的回滾功能。
MULTI:開啓事務,告訴Redis接下來輸入的多條命令不立馬執行,而是先存起來;
EXEC:提交事務,將一組命令提交併按照輸入順序依次執行。
錯誤處理
語法錯誤
語法錯誤指的是命令不存在或命令參數不對。一組命令中,只要有一個語法錯誤,執行EXEC後Redis會直接返回錯誤,連語法正確的也不會執行。(PS:僅針對Redis2.6.5及以後的版本來說)
運行錯誤
運行錯誤指在命令執行時出現的錯誤,比如使用散列類型的命令操作集合類型的鍵,這種錯誤在實際執行之前Redis是無法發現的,所以在事務裏這樣的命令會被Redis接受並執行的。如果事務裏的一條命令出現了運行錯誤,事務裏其他命令依然會繼續執行。
WATCH命令
介紹
WATCH命令可以監控一個鍵,當該鍵對應的值被修改後,可以阻止之後對該鍵值進行修改的一個事務的執行。
如圖,在WATCH “key”這個鍵後,又SET了該鍵的值,所以後面的事務沒有執行成功。
執行EXEC命令會取消對所有鍵的WATCH監控,如果不想執行事務中的命令,也可以用UNWATCH來取消對所有鍵的監控。
應用場景
在什麼情景下需要使用WATCH?比如說,你先要GET某個鍵的值,對值進行一些操作之後,再SET該鍵的新值,但這樣可能會出現競態條件。雖然Redis事務可以執行一組命令並且也是原子的,但是在Redis事務中你沒法獲取上一條命令的返回值,因爲所有命令都是執行完EXEC命令之後一起依次執行的,返回值是一起返回的。所以我們可以用WATCH+事務來完成上述GET和SET操作,假如在執行事務之前該鍵值被修改(也就是出現了競態條件),事務會執行失敗,這時你可以選擇重試。
Redis事務的Java demo(使用RedisTemplate)
Object result = stringRedisTemplate.execute(new SessionCallback<Object>() {
@Override
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
//一些Redis命令
return operations.exec();
}
});
參考資料
- 《Redis入門指南》第2版,李子驊