RedisTemplate实现事物问题剖析和解决
?
一、問題描述
? ? ?Redis為單進程單線程模式,采用隊列模式將并發(fā)訪問變成串行訪問,Redis對事物支持不會很復(fù)雜,當一個客服端連接Redis服務(wù)時,發(fā)出了MULTI命令時,這個連接會進入事物,在執(zhí)行MULTI命令之后,執(zhí)行所有的命令都不會執(zhí)行,會先放到一個隊列中,會提示正在Query,當最后執(zhí)行EXEC命令之后,Redis會按照之前的進入隊列的順序,執(zhí)行命令。
? ? ??Spring?Data Redis 是對JRedis的客服端進行很好的封裝,?spring?Data Redis的RedisTemplate提供了MULTI、EXEC命令進行封裝,但RedisTemplate先執(zhí)行調(diào)用MULTI方法,然后在執(zhí)行其它的命令,最后執(zhí)行EXEC方法時,會出現(xiàn)報錯:Caused by:Redis.clents.jedis.exceptions.JedisDataException:ERR EXEC without MULTI問題。
?
二、原因分析
? ???Redis為單進程單線程模式,采用隊列模式將并發(fā)訪問變成串行訪問,我們需要重新添加數(shù)據(jù),對原先的數(shù)據(jù)進行刪除,在多個線程情況下數(shù)據(jù)會丟失,所以我們需要事務(wù)完成相應(yīng)的效果。
? ? ??Spring Data Redis的RedisTemplate提供了MULTI、EXEC命令進行封裝,遠看可以解決問題時,代碼實現(xiàn):
? ? ?
[java]?view plaincopy?
? ? ? ?結(jié)果保 錯誤:
? ? ? ? ?
? ? ? ?
? ? ? ? ? ??我們查詢multi、delete等源代碼,發(fā)現(xiàn)會執(zhí)行RedisTemplate類中execute()方法進行跟蹤發(fā)現(xiàn) RedisCallback中doInRedis獲取的RedisConnection每次都是新的,所以才導(dǎo)致該問題。
? ? ? ? 分析Redis源代碼:
? ? ? ? ? ? ? ?我們查看multi實現(xiàn)
? ? ? ? ? ? ? ? ? 跟蹤發(fā)現(xiàn)RedisConnection conn每次都是新的,導(dǎo)致出現(xiàn)那個錯誤三、解決方案
? ? ???只能自己實現(xiàn)RedisCallBack底層,采用RedisTemplate的SesionCallback來完成在同一個Connection中,完成多個操作的方法:
總結(jié)
以上是生活随笔為你收集整理的RedisTemplate实现事物问题剖析和解决的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我理解的几种字符编码方式
- 下一篇: 数据库中间件MyCAT源码分析:调试环境