redis的一些知識-redis事務multi
阿新 • • 發佈:2018-12-25
redis是有事務的,但是不同於mysql的事務。
redis的事務是由multi和exec包圍起來的部分,當發出multi命令時,redis會進入事務,redis會進入阻塞狀態,不再響應任何別的客戶端的請求,直到發出multi命令的客戶端再發出exec命令為止。那麼被multi和exec包圍的命令會進入獨享redis的過程,直到執行完畢。
事務同命令一樣都是Redis的最小執行單位,一個事務中的命令要麼都執行,要麼都不執行。如果在傳送EXEC命令前客戶端斷線了,則Redis會清空事務佇列,事務中的所有命令都不會執行。而一旦客戶端傳送了EXEC命令,所有的命令就都會被執行,即使此後客戶端斷線也沒關係,因為Redis中已經記錄了所有要執行的命令。
那麼在事務過程中出錯了怎麼辦?注意,這裡只考慮執行時錯誤,不考慮redis語法錯誤,因為通過redis的api進行的命令是沒有語法上的錯誤的。如果需要執行1,2,3個步驟,其中2在執行時出錯了,那麼不像mysql的事務那樣會回滾,redis是繼續往下執行,直到執行完畢,該事務算結束。
注意,redis是不會回滾的。
通過這種簡單的獨享型的事務機制,redis能避免多個客戶端同時訪問時,出現讀寫不一致的情況,來完成原子性事務。
spring data redis提供的RedisTemplate中有使用事務的方法,程式碼如下:
即是在SessionCallback回撥方法中,通過multi和exec來包圍的部分。//execute a transaction List<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() { public List<Object> execute(RedisOperations operations) throws DataAccessException { operations.multi(); operations.opsForSet().add("key", "value1"); // This will contain the results of all ops in the transaction return operations.exec(); } }); System.out.println("Number of items added to set: " + txResults.get(0));
和pipeline類似,返回值也是一個List,就是執行的各命令結果的集合。