欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學(xué)習(xí)spring事務(wù)與消息隊(duì)列

 更新時(shí)間:2016年10月12日 14:47:26   作者:登頂  
這篇文章主要為大家詳細(xì)介紹了spring事務(wù)與消息隊(duì)列,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

在開(kāi)發(fā)過(guò)程中,遇到一個(gè)bug,產(chǎn)生bug的原因是spring事務(wù)提交晚于消息隊(duì)列的生產(chǎn)消息,導(dǎo)致消息隊(duì)列消費(fèi)消息時(shí)獲取到的數(shù)據(jù)不正確。這篇文章介紹問(wèn)題的產(chǎn)生和一步步的解決過(guò)程。

一.問(wèn)題的產(chǎn)生:

場(chǎng)景還原:接口中的一個(gè)方法,首先修改訂單狀態(tài),然后向消息隊(duì)列中生產(chǎn)消息,消息隊(duì)列的消費(fèi)者獲取到消息檢測(cè)訂單狀態(tài),發(fā)現(xiàn)訂單狀態(tài)未更改。

代碼:

@Service(orderApi)
public class OrderApiImpl implements OrderApi {
  @Resource MqService mqService;
  @OrderDao orderDao;
   
  public void push(String orderId) {
    // 更新訂單狀態(tài),之前的狀態(tài)是1
    updateStatus(orderId, 3);
    // 產(chǎn)生消息
    mqService.produce(orderId);
  }
  public viod updateStatus(String orderId, Integer status) {
    orderDao.updateStatus(orderId, status);
  }
}

問(wèn)題產(chǎn)生原因:orderApi中的所有方法都有事務(wù),事務(wù)類型PROPAGATION_REQUIRED,所以push方法對(duì)數(shù)據(jù)的操作會(huì)在push代碼全部執(zhí)行之后提交,而在事務(wù)提交之前消息隊(duì)列的消息已經(jīng)產(chǎn)生所以消息隊(duì)列中消費(fèi)到的訂單從數(shù)據(jù)庫(kù)查詢出的狀態(tài)可能還為1。為了讓bug現(xiàn)象更明顯,可以在push方法最后添加:

try {
  Thread.sleep(10000);
} catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

這樣就會(huì)發(fā)現(xiàn)消費(fèi)消息時(shí),訂單狀態(tài)一定是未修改的。 

二.問(wèn)題的解決:

解決方案:在更新數(shù)據(jù)時(shí),新建一個(gè)事物,保證更新代碼執(zhí)行完成后,更新數(shù)據(jù)庫(kù)的事務(wù)已被提交。(確保消息產(chǎn)生前數(shù)據(jù)庫(kù)操作已提交)

按照上述方案,我首先想到的是直接修改updateStatus方法的事務(wù)類型;我將此方法的事務(wù)類型改為PROPAGATION_REQUIRES_NEW(新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起)。

但是這么做有兩點(diǎn)不合適:

  1.強(qiáng)制修改了updateStaus的事務(wù)類型,可能影響其他流程。

  2.未起到作用,updateStaus方法中沒(méi)有新建事務(wù)。

關(guān)于第二點(diǎn)的解釋:spring添加事務(wù)是通過(guò)BeanNameAutoProxyCreator實(shí)現(xiàn)的動(dòng)態(tài)代理,只是給bean對(duì)象添加了事務(wù),現(xiàn)在在類內(nèi)部調(diào)用方法,是不會(huì)觸發(fā)新事物的創(chuàng)建的。

所以在經(jīng)過(guò)以上嘗試后,我創(chuàng)建了一個(gè)新的類:

@Service("orderExtApi")
public class OrderExtApiImpl {
  @Resource OrderApi orderApi;
   
  public void updateStatusNewPropagation(String orderId) {
    orderApi.updateStatus(orderId);
  }
}

并為updateStatusNewPropagation方法添加事務(wù)PROPAGATION_REQUIRES_NEW

這個(gè)類就只是為了給orderApi中的updateStaus方法新起一個(gè)事務(wù)。

ok,到此為止bug已經(jīng)解決了。

但是代碼中還是存在問(wèn)題:對(duì)數(shù)據(jù)庫(kù)的操作已經(jīng)提交,如果生產(chǎn)消息出現(xiàn)異常對(duì)業(yè)務(wù)邏輯來(lái)說(shuō)還是錯(cuò)誤的。所以需要檢測(cè)消息的產(chǎn)生是否完成。

最終orderApi中的代碼如下:

@Service(orderApi)
public class OrderApiImpl implements OrderApi {
  @Resource MqService mqService;
  @Resource OrderDao orderDao;
  @Resource OrderExtApiImpl orderExtApi;
   
  public void push(String orderId) {
    // 更新訂單狀態(tài),之前的狀態(tài)是1
    orderExtApi.updateStatusNewPropagation(orderId, 3);
    // 產(chǎn)生消息--produce會(huì)檢測(cè)是否出現(xiàn)異常 當(dāng)返回1時(shí)表示生產(chǎn)消息成功
    Response response = mqService.produce(orderId);
    if (response.getCode() != 1) {
      log.info("消息隊(duì)列生產(chǎn)消息異常:" + response.getErrorMsg())
      // 生產(chǎn)消息異常,重置狀態(tài) 等待下次重新執(zhí)行
      orderExtApi.updateStatusNewPropagation(orderId, 1);
    }
     
  }
  public viod updateStatus(String orderId, Integer status) {
    orderDao.updateStatus(orderId, status);
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java輕松實(shí)現(xiàn)在Excel中添加超鏈接功能

    Java輕松實(shí)現(xiàn)在Excel中添加超鏈接功能

    這篇文章主要為大家詳細(xì)介紹了Java如何輕松實(shí)現(xiàn)在Excel中添加超鏈接功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • 詳解Java中Math.round()的取整規(guī)則

    詳解Java中Math.round()的取整規(guī)則

    這篇文章主要介紹了詳解Java中Math.round()的取整規(guī)則,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)項(xiàng)目之在線服裝銷售商城系統(tǒng)的實(shí)現(xiàn)流程

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)項(xiàng)目之在線服裝銷售商城系統(tǒng)的實(shí)現(xiàn)流程

    基礎(chǔ)掌握怎么樣,用實(shí)戰(zhàn)檢驗(yàn)就知道了,本篇文章手把手帶你用java+SpringBoot+Maven+Vue+mysql實(shí)現(xiàn)一個(gè)在線服裝銷售商城系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2022-01-01
  • elasticsearch源碼分析index?action實(shí)現(xiàn)方式

    elasticsearch源碼分析index?action實(shí)現(xiàn)方式

    這篇文章主要為大家介紹了elasticsearch源碼分析index?action實(shí)現(xiàn)方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 最新評(píng)論