日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

RedisTemplate实现事物问题剖析和解决

發(fā)布時間:2025/3/20 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RedisTemplate实现事物问题剖析和解决 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

一、問題描述

? ? ?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
  • stringRedisTemplate.multi();??
  • stringRedisTemplate.delete("test");??
  • stringRedisTemplate.opsForValue().set("test","2");??
  • stringRedisTemplate.exec();??
  • ?

    ? ? ? ?結(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中,完成多個操作的方法:

  • SessionCallback<Object>???sessionCallback=new?SessionCallback<Object>(){??
  • ??@Override??
  • ???public?Object?execute(RedisOperations?operations)?throws?DataAccessException{??
  • operations.multi();??
  • operations.delete("test");??
  • operations.opsForValue.set("test","2");??
  • Object?val=operations.exec();??
  • return?val;??
  • }??
  • }??
  • StringRedisTemplate.execute(sessionCallback);?
  • 總結(jié)

    以上是生活随笔為你收集整理的RedisTemplate实现事物问题剖析和解决的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。