亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

redis分布式鎖的問題與解決方法

2020-10-28 21:29:39
字體:
來源:轉載
供稿:網友

分布式鎖

在分布式環境中,為了保證業務數據的正常訪問,防止出現重復請求的問題,會使用分布式鎖來阻攔后續請求。我們先寫一段有問題的業務代碼:

public void doSomething(String userId){  User user=getUser(userId);  if(user==null){   user.setUserName("xxxxx");   user.setUserId(userId);   insert(user);   return;  }  update(user); }

上面的代碼很簡單,查詢db中有沒有對應的user數據,如果有的話,執行更新操作,如果沒有則插入。

我們知道,上面的代碼是線程不安全的,在多線程的環境中,就會出現問題。為了能夠保證數據的正確性,在單機環境下,我們可以使用synchronized的方法,來保證線程安全,具體修改:

public synchronized void doSomething(String userId){  User user=getUser(userId);  if(user==null){   user.setUserName("xxxxx");   user.setUserId(userId);   insert(user);   return;  }  update(user); }

在單機器的環境下,能夠解決線程安全的問題,那在分布式環境下呢? 這個時候需要用到分布式鎖.

分布式鎖需要借助其他組件來實現,常用的有redis和zookeeper。下面我們就用redis的實現,來說明下問題,分布式鎖具體的實現方法如下

public void doSomething(String userId){  String lock=RedisUtils.get("xxxx"+userId);  if(StringUtils.isNotEmpty(lock)){//說明當前userId已經被鎖定   return;  }  RedisUtils.set("xxxx"+userId,userId,1000);//鎖定10s  User user=getUser(userId);  if(user==null){   insert(user);   RedisUtils.delete("xxxx"+userId);   return;  }  update(user);  RedisUtils.delete("xxxx"+userId);   }

上面的代碼解決了在分布式環境中的并發的問題。但同樣需要考慮一個問題,如果insert操作和update操作異常了,分布式鎖不會釋放,后續的請求還會被攔截。

所以我們再優化,增加對異常的捕獲。

public void doSomething(String userId){  try {    String lock=RedisUtils.get("xxxx"+userId);    if(StringUtils.isNotEmpty(lock)){//說明當前userId已經被鎖定     return;    }    RedisUtils.set("xxxx"+userId,userId,1000);//鎖定1s    User user=getUser(userId);    if(user==null){     insert(user);     return;    }    update(user);  }  catch(Exception ex){  }  finally{   RedisUtils.delete("xxxx"+userId);  } }

現在即使是程序異常了,鎖會自動釋放。但redis的get和set也會存在并發問題,我們再繼續優化,使用redis中的setnx方法

public void doSomething(String userId){  try {    boolean lock=RedisUtils.setnx("xxxx"+userId,userId,1000);//鎖定1s    if(!lock){//說明當前userId已經被鎖定     return;    }    User user=getUser(userId);    if(user==null){     insert(user);     return;    }    update(user);  }  catch(Exception ex){  }  finally{   RedisUtils.delete("xxxx"+userId);  } }

上面的代碼好像沒有什么問題了,但也存在很大的隱患。 我們分析下,假設第一個請求過來,執行鎖定成功,程序開始運行,但是insert和update操作阻塞了1s,第二個請求過來,鎖的緩存已經過期,第二個執行鎖定成功,這個時候第一個請求完成了鎖被釋放,第二個請求的鎖就被第一次請求釋放了,第三次的請求就會造成線程不安全問題。

怎么再去優化呢?問題主要是出現在第一次請求誤刪鎖的問題,所以我們在移除鎖的時候要判斷能否移除。

思路:我們在鎖定的時候,value使用當前的時間戳,刪除時判斷是否過期如果不過期就不要刪除,具體代碼如下:

public void doSomething(String userId){  try {    boolean lock=RedisUtils.setnx("xxxx"+userId,LocalDateTime.now(),1000);//鎖定10s    if(!lock){//說明當前userId已經被鎖定     return;    }    User user=getUser(userId);    if(user==null){     insert(user);     return;    }    update(user);  }  catch(Exception ex){  }  finally{   LocalDateTime lockTIme= RedisUtils.get("xxxx"+userId);   if(lockTIme.compare(LocalDateTime.now())<0){    //說明已經過期,可以刪除key    RedisUtils.delete("xxxx"+userId);   }  } }

 這樣即使出現阻塞,第二次的時間戳覆蓋了第一次的鎖定,這樣即使第一次完成了,也不會釋放鎖。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久国产视频网站| 欧美日韩性视频| 成人精品视频99在线观看免费| 97在线免费观看视频| 亚洲国产精品专区久久| 欧美午夜精品久久久久久浪潮| 亚洲91精品在线| 亚洲成色777777女色窝| 国产精品一区电影| 中日韩午夜理伦电影免费| 精品国产老师黑色丝袜高跟鞋| 亚洲日本成人网| 日韩欧美国产一区二区| 欧美劲爆第一页| 国产精品劲爆视频| 久久国产天堂福利天堂| 亚洲国产精品久久久久秋霞蜜臀| y97精品国产97久久久久久| 欧美又大粗又爽又黄大片视频| 日韩最新av在线| 日韩电影中文字幕一区| 国产精品人成电影| 欧美裸体xxxxx| 欧美日韩综合视频网址| 国内精品视频一区| 97久久精品国产| 国产精品丝袜一区二区三区| 国产精品久久久久久亚洲影视| 大荫蒂欧美视频另类xxxx| 亚洲第一区中文99精品| 国产精品欧美一区二区三区奶水| 久久久国产成人精品| 国产丝袜精品第一页| 亚洲一二三在线| 欧美大人香蕉在线| 久久福利网址导航| 91久久国产精品91久久性色| 日韩免费在线播放| 久久精品中文字幕免费mv| 欧美成人精品不卡视频在线观看| 亚洲va码欧洲m码| 欧美xxxx做受欧美| 136fldh精品导航福利| 视频一区视频二区国产精品| 大桥未久av一区二区三区| 国产成人精品免高潮在线观看| 97色伦亚洲国产| 正在播放欧美一区| 69视频在线免费观看| 中文字幕久热精品视频在线| 亚洲国产欧美久久| 庆余年2免费日韩剧观看大牛| 2018国产精品视频| 国产成人一区二区三区| 精品国产一区二区三区在线观看| 在线视频精品一| 日韩日本欧美亚洲| 久久影院在线观看| 日韩中文字幕在线| 亚洲性生活视频在线观看| 欧美激情亚洲一区| 欧美国产精品人人做人人爱| 亚洲美女在线观看| 久久五月情影视| 国产视频精品一区二区三区| www欧美日韩| 亚洲国产精品va在线看黑人| 88xx成人精品| 久久精品一偷一偷国产| 日本不卡高字幕在线2019| 欧美视频中文在线看| 国产精品成人av性教育| 亚洲第一av网| 亚洲精品网址在线观看| 欧美大片在线看| 91亚洲国产成人久久精品网站| 色悠悠国产精品| 国产精品美乳在线观看| 久久激情五月丁香伊人| 欧美大片在线看| 成人国产亚洲精品a区天堂华泰| 国产在线一区二区三区| 成人网页在线免费观看| 国产成人一区二区三区电影| 欧美人与性动交a欧美精品| 北条麻妃99精品青青久久| 久热爱精品视频线路一| 欧美日韩电影在线观看| 国产日韩精品在线播放| 91影视免费在线观看| 色妞在线综合亚洲欧美| 久久九九精品99国产精品| 亚洲网站在线播放| 北条麻妃久久精品| 亚洲国内精品在线| 狠狠躁夜夜躁人人爽超碰91| 久久成年人免费电影| 国产精品r级在线| 亚洲性线免费观看视频成熟| 亚洲国产天堂网精品网站| 色婷婷综合成人| 中文字幕不卡在线视频极品| 欧美日韩中文在线| 91在线视频导航| 成人黄色片网站| 一区二区在线视频播放| 国产成人精品av在线| 久久久久久亚洲精品不卡| 韩国视频理论视频久久| 成人a级免费视频| 国产亚洲精品一区二区| 色偷偷av一区二区三区| 国产精品精品视频| 日韩在线免费视频观看| 亚洲男人天堂久| xxx成人少妇69| 欧美在线不卡区| 国产亚洲一区二区在线| 97在线视频免费播放| 亚洲国产97在线精品一区| 欧美成人免费全部| 91精品国产综合久久香蕉的用户体验| 国产在线视频91| 日韩激情av在线播放| 亚洲18私人小影院| 亚洲最大中文字幕| 一本色道久久综合狠狠躁篇怎么玩| 日本中文字幕成人| 亚洲国产精品女人久久久| 国产精品爽爽爽爽爽爽在线观看| 久久久精品国产| 亚洲电影免费观看高清完整版| 精品亚洲国产成av人片传媒| 国产成人综合一区二区三区| 91av中文字幕| 日韩av免费观影| 一道本无吗dⅴd在线播放一区| 国产精品久久久久9999| 一区二区三区视频免费在线观看| 久久久亚洲国产| 久久久精品中文字幕| 亚洲精品成人久久| 日韩精品在线看| 亚洲第一视频网| 精品中文视频在线| 亚洲欧美一区二区三区情侣bbw| 中文字幕亚洲欧美一区二区三区| 亚洲欧美一区二区三区情侣bbw| 国语对白做受69| 黑人巨大精品欧美一区二区| 97色在线视频观看| 亚洲在线免费观看| 国产91精品久久久久久| 亚洲风情亚aⅴ在线发布| 97超级碰碰碰| 亚洲精品在线91| 国产精品免费一区豆花| 久久久国产在线视频| 亚洲韩国欧洲国产日产av| 欧美尤物巨大精品爽| 精品精品国产国产自在线| 亚洲第一区中文99精品| 亚洲三级免费看| 日韩国产精品亚洲а∨天堂免|