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

淺析SpringBoot微服務(wù)中異步調(diào)用數(shù)據(jù)提交數(shù)據(jù)庫(kù)的問(wèn)題

 更新時(shí)間:2022年07月25日 14:28:23   作者:趙四司機(jī)  
這篇文章主要介紹了SpringBoot微服務(wù)中異步調(diào)用數(shù)據(jù)提交數(shù)據(jù)庫(kù)的問(wèn)題,今天本文涉及到的知識(shí)點(diǎn)不難,都是很簡(jiǎn)單的crud操作,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

前言:

1.前面基于Springboot的單體項(xiàng)目介紹已經(jīng)完結(jié)了,至于項(xiàng)目中的其他功能實(shí)現(xiàn)我這里就不打算介紹了,因?yàn)樯婕暗闹R(shí)點(diǎn)不難,而且都是簡(jiǎn)單的CRUD操作,假如有興趣的話可以私信我我再看看要不要寫(xiě)幾篇文章做個(gè)介紹。

2.完成上一階段的學(xué)習(xí),我就投入到了微服務(wù)的學(xué)習(xí)當(dāng)中,所用教程為B站上面黑馬的微服務(wù)教程。由于我的記性不是很好,所以對(duì)于新事物的學(xué)習(xí)我比較喜歡做筆記以加強(qiáng)理解,在這里我會(huì)將筆記的重點(diǎn)內(nèi)容做個(gè)總結(jié)發(fā)布到“微服務(wù)學(xué)習(xí)”筆記欄目中。我是趙四,一名有追求的程序員,希望大家能多多支持,能給我點(diǎn)個(gè)關(guān)注就更好了。

一: 同步&異步

1.同步與異步的概念

在進(jìn)行問(wèn)題探討之前,我們有必要先了解一下什么是同步什么是異步。先來(lái)個(gè)官方點(diǎn)的說(shuō)法:同步和異步關(guān)注的是消息通信機(jī)制 (synchronous communication/ asynchronous communication)。同步,就是調(diào)用某個(gè)東西是,調(diào)用方得等待這個(gè)調(diào)用返回結(jié)果才能繼續(xù)往后執(zhí)行。異步,和同步相反 調(diào)用方不會(huì)理解得到結(jié)果,而是在調(diào)用發(fā)出后調(diào)用者可用繼續(xù)執(zhí)行后續(xù)操作,被調(diào)用者通過(guò)狀體來(lái)通知調(diào)用者,或者通過(guò)回掉函數(shù)來(lái)處理這個(gè)調(diào)用。

可能你會(huì)就得有點(diǎn)懵?下面我們舉個(gè)簡(jiǎn)單點(diǎn)的例子:就好像你去買(mǎi)水果,發(fā)現(xiàn)水果賣(mài)完了,這時(shí)候水果還在來(lái)的路上,你選擇等待,直到水果到了你買(mǎi)完才離開(kāi),這就是同步;而你知道水果賣(mài)完了,你跟店家說(shuō)你要買(mǎi)什么然后店家到時(shí)候給你送貨上門(mén),你只是跟店家說(shuō)了一句之后便離開(kāi)去干其他事情了,這就是異步。

2.同步方法調(diào)用&異步方法調(diào)用

前面介紹完同步和異步的概念之后,我們要把它代入到我們的代碼世界里面,在代碼世界里面,同步和異步一般體現(xiàn)在方法調(diào)用和http請(qǐng)求(ajax發(fā)送異步請(qǐng)求)上面,這里主要介紹方法調(diào)用。

2.1:同步方法調(diào)用

所謂同步方法調(diào)用,就是一個(gè)方法A調(diào)用方法B之后,方法A必須要等待方法B執(zhí)行完才能繼續(xù)執(zhí)行,要是方法B沒(méi)執(zhí)行完方法A就必須一直等待,見(jiàn)下圖:

2.2:異步方法調(diào)用

異步方法調(diào)用指的是當(dāng)方法A調(diào)用方法B之后,方法A不需要等待方法B執(zhí)行完畢再去干別的事,方法A只需要發(fā)起調(diào)用請(qǐng)求之后便繼續(xù)執(zhí)行自己的程序,方法B在另外一個(gè)線程里面執(zhí)行,兩者互不干擾,見(jiàn)下圖:

二:?jiǎn)栴}引入

1.功能需求

程序中我要實(shí)現(xiàn)的功能是作者發(fā)布文章之后線程A完成文章的保存工作,且在線程A里面要開(kāi)啟異步調(diào)用線程B實(shí)現(xiàn)文章的審核功能。部分代碼如下

@Override
@Async //表明這是一個(gè)異步方法
public void AutoScanTextAndImage(Integer id) throws TencentCloudSDKException {
    log.info("開(kāi)始進(jìn)行文章審核...");
    WmNews wmNews = wmNewsService.getById(id);
    if(wmNews == null) {
        throw new RuntimeException("WmAutoScanServiceImpl-文章信息不存在");
    }
    if(wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
        //1.提取文章文本及圖片
        Map<String,Object> map = getTextAndImages(wmNews);
 
        //2.檢測(cè)文本
        //2.1提取文本
        String content = ((StringBuilder) map.get("content")).toString();
        //2.2調(diào)用騰訊云進(jìn)行文本檢測(cè)
        Boolean THandleResult = handleTextScan(content, wmNews);
        if(!THandleResult) return;
 
        //3.檢測(cè)圖片
        //3.1提取圖片
        List<String> imageUrl = (List<String>) map.get("images");
        //3.2調(diào)用騰訊云對(duì)圖片進(jìn)行檢測(cè)
        Boolean IHandleresult = handleImageScan(imageUrl, wmNews);
        if(!IHandleresult) return;
 
        //4,審核成功
        //4.1保存文章
        log.info("檢測(cè)到文章無(wú)違規(guī)內(nèi)容");
        ResponseResult responseResult = saveAppArticle(wmNews);
        if(!responseResult.getCode().equals(200)) {
            throw new RuntimeException("WmAutoScanServiceImpl-文章審核,保存文章失敗");
        }
        //4.2回填article_id
        wmNews.setArticleId((Long) responseResult.getData());
        wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
        wmNews.setReason("審核成功");
        
        wmNewsService.updateById(wmNews);
    }
}
@Autowired
private WmAutoScanService wmAutoScanService;
/**
 * 提交文章
 * @param dto
 * @return
 */
@Override
public ResponseResult submitNews(WmNewsDto dto) throws TencentCloudSDKException {
    //1.參數(shù)校驗(yàn)
    if(dto == null || dto.getContent().length() == 0) {
        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }
 
    //2.保存或修改文章
    //2.1屬性拷貝
    WmNews wmNews = new WmNews();
    BeanUtils.copyProperties(dto,wmNews);
    //2.2設(shè)置封面圖片
    if(dto.getImages() != null && dto.getImages().size() != 0) {
        String images = StringUtils.join(dto.getImages(), ",");
        wmNews.setImages(images);
    }
    //2.3封面類(lèi)型為自動(dòng)
    if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)) {
        wmNews.setType(null);
    }
    saveOrUpdateWmNews(wmNews);
 
    //3.判斷是否為草稿
    if(dto.getStatus().equals(WmNews.Status.NORMAL.getCode())) {
        //直接保存結(jié)束
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
 
    //4.不是草稿
    //4.1保存文章圖片素材與文章關(guān)系
    //4.1.1提取圖片素材列表
    List<String> imagesList = getImagesList(dto);
    //4.1.2保存
    saveRelatedImages(imagesList,wmNews.getId(),WemediaConstants.WM_CONTENT_REFERENCE);
    //4.2保存封面圖片和文章關(guān)系
    saveRelatedCover(dto,imagesList,wmNews);
 
    //5.審核文章(異步調(diào)用)
    wmAutoScanService.AutoScanTextAndImage(wmNews.getId());
    
    return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

2.問(wèn)題引出

代碼看著沒(méi)有什么問(wèn)題,但是運(yùn)行起來(lái)之后發(fā)現(xiàn)出現(xiàn)以下錯(cuò)誤:

這是手動(dòng)拋出的異常,拋出位置為:

WmNews wmNews = wmNewsService.getById(id);
if(wmNews == null) {
    throw new RuntimeException("WmAutoScanServiceImpl-文章信息不存在");
}

可以看到查詢出的文章對(duì)象為空。

3.問(wèn)題剖析

既然這里出現(xiàn)空對(duì)象,那么是不是因?yàn)闆](méi)有進(jìn)行數(shù)據(jù)插入呢?查看前面的日志信息,可以看到確實(shí)插入了一條數(shù)據(jù):

接下來(lái)進(jìn)行的操作時(shí)查詢?cè)摋l數(shù)據(jù),查看MySQL日志信息:

可以看到查出的數(shù)據(jù)為空,那么為什么會(huì)出現(xiàn)這樣的情況呢?要注意的是,這里開(kāi)啟了異步方法調(diào)用,這時(shí)候線程A是負(fù)責(zé)將數(shù)據(jù)保存的,而線程B是負(fù)責(zé)對(duì)文章進(jìn)行審核的,而且線程A開(kāi)啟了事務(wù)支持,會(huì)不會(huì)是因?yàn)檫@兩個(gè)方法都被認(rèn)為是同一個(gè)事務(wù)所以事務(wù)還沒(méi)結(jié)束線程B查詢不到數(shù)據(jù)呢?這應(yīng)該是不可能的,因?yàn)橐雽?shí)現(xiàn)jdbc事務(wù), 就必須是在同一個(gè)連接對(duì)象中操作,而我們可以看到,在進(jìn)行查詢操作時(shí)候是創(chuàng)建了一個(gè)新的連接的:

那這時(shí)候只有一種可能,就是由于A開(kāi)啟了事務(wù),這時(shí)候B線程是異步執(zhí)行的,只要線程A還沒(méi)有執(zhí)行完畢,數(shù)據(jù)就不會(huì)被提交到數(shù)據(jù)庫(kù)中,這時(shí)候線程B嘗試去數(shù)據(jù)庫(kù)中獲取該數(shù)據(jù)顯然是獲取不到的。

三:?jiǎn)栴}解決

有了以上假設(shè),實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),下面通過(guò)調(diào)試來(lái)檢驗(yàn),首先在線程A上加上一句日志打印信息,看看線程B執(zhí)行時(shí)線程A是否執(zhí)行完畢(關(guān)系到數(shù)據(jù)時(shí)候已經(jīng)提交)。通過(guò)斷點(diǎn)進(jìn)行調(diào)試:

可以看到這時(shí)候是能夠獲取到數(shù)據(jù)的,那么假如我在查詢之前讓線程休眠0.5秒呢?

可以看到這時(shí)候成功獲取到數(shù)據(jù),說(shuō)明就是跟數(shù)據(jù)提交時(shí)間有關(guān)。

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源配置的示例詳解

    SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源配置的示例詳解

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源配置的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • 基于Java代碼配置MyBatis Generator

    基于Java代碼配置MyBatis Generator

    這篇文章主要介紹了基于Java代碼配置MyBatis Generator,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 淺析java快速排序算法

    淺析java快速排序算法

    這篇文章主要介紹了淺析java快速排序算法,需要的朋友可以參考下
    2015-02-02
  • Java實(shí)現(xiàn)鏈棧的示例代碼

    Java實(shí)現(xiàn)鏈棧的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)來(lái)實(shí)現(xiàn)棧,也就是鏈棧的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-11-11
  • Java判斷本機(jī)IP地址類(lèi)型的方法

    Java判斷本機(jī)IP地址類(lèi)型的方法

    Java判斷本機(jī)IP地址類(lèi)型的方法,需要的朋友可以參考一下
    2013-03-03
  • SpringBoot如何進(jìn)行業(yè)務(wù)校驗(yàn)實(shí)例詳解

    SpringBoot如何進(jìn)行業(yè)務(wù)校驗(yàn)實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot如何進(jìn)行業(yè)務(wù)校驗(yàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-01-01
  • SpringBoot使用Prometheus實(shí)現(xiàn)監(jiān)控

    SpringBoot使用Prometheus實(shí)現(xiàn)監(jiān)控

    在當(dāng)今的軟件開(kāi)發(fā)世界中,監(jiān)控是至關(guān)重要的一部分,本文主要介紹了如何在Spring Boot應(yīng)用程序中使用Prometheus進(jìn)行監(jiān)控,以幫助大家更好地理解和管理您的應(yīng)用程序,有需要的可以參考下
    2023-10-10
  • java正則表達(dá)式的簡(jiǎn)單運(yùn)用

    java正則表達(dá)式的簡(jiǎn)單運(yùn)用

    這篇文章主要為大家詳細(xì)介紹了java正則表達(dá)式的簡(jiǎn)單運(yùn)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • SpringBoot打包發(fā)布到linux上(centos 7)的步驟

    SpringBoot打包發(fā)布到linux上(centos 7)的步驟

    這篇文章主要介紹了SpringBoot打包發(fā)布到linux上(centos 7)的步驟,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-12-12
  • 詳解Java的線程的優(yōu)先級(jí)以及死鎖

    詳解Java的線程的優(yōu)先級(jí)以及死鎖

    這篇文章主要介紹了詳解Java的線程的優(yōu)先級(jí)以及死鎖,線程是Java編程學(xué)習(xí)中的重要知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論