日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
接口中的大事務(wù),該如何進(jìn)行優(yōu)化?

作為后端開(kāi)發(fā)的程序員,我們常常會(huì)的一些相對(duì)比較復(fù)雜的邏輯,比如我們需要給前端寫一個(gè)調(diào)用的接口,這個(gè)接口需要進(jìn)行相對(duì)比較復(fù)雜的業(yè)務(wù)邏輯操作,比如會(huì)進(jìn)行,查詢、遠(yuǎn)程接口或本地接口調(diào)用、更新、插入、計(jì)算等一些邏輯,將最終接口的返回結(jié)果給到前端,而經(jīng)過(guò)這么一系列的業(yè)務(wù)邏輯操作,接口對(duì)DB的操作、對(duì)代碼業(yè)務(wù)邏輯判斷、進(jìn)行接口調(diào)用這些都是需要時(shí)間的,而只要這是一個(gè)事務(wù)操作,每次對(duì)數(shù)據(jù)庫(kù)進(jìn)行的交互都會(huì)產(chǎn)生一條事務(wù)記錄。

那么這樣就會(huì)對(duì)我們接口返回的效率產(chǎn)生影響,而且這個(gè)影響是隨著數(shù)據(jù)量的增長(zhǎng)而增長(zhǎng)的,這時(shí)候我們就需要對(duì)一整個(gè)大事務(wù)進(jìn)行拆分,從而提升整體接口的效率。

何為大事務(wù)

就拿我最近開(kāi)發(fā)寫的一個(gè)接口來(lái)說(shuō)吧,大致是這么一個(gè)邏輯,我需要根據(jù)頁(yè)面的提交的數(shù)據(jù)生成一個(gè)收款單,整體接口處理的業(yè)務(wù)如下,我把它們寫在了一個(gè)接口里,可以理解為這是一個(gè)大事物,這個(gè)接口執(zhí)行的時(shí)間是相對(duì)比較長(zhǎng)的,而且將這些邏輯全部寫在一個(gè)接口里面,本身來(lái)說(shuō)也是不太合理的。

圖片

大事務(wù)存在的一些問(wèn)題

并發(fā)數(shù)據(jù)不一致

不加鎖的情況下,由于種種原因第一次接口的調(diào)用還沒(méi)執(zhí)行完,還在等待第三方的調(diào)用回寫數(shù)據(jù),第二次調(diào)用又進(jìn)來(lái)對(duì)數(shù)據(jù)進(jìn)行了更改,第二次調(diào)用先執(zhí)行完,這時(shí)候第一次接口調(diào)用拿到了第三方接口的返回,去回寫狀態(tài)發(fā)現(xiàn)已經(jīng)被更新,導(dǎo)致無(wú)效操作。

加鎖容易阻塞

加鎖的情況下, 不會(huì)出現(xiàn)數(shù)據(jù)不一致情況,但是由于大事物執(zhí)行時(shí)間較長(zhǎng),容易造成鎖超時(shí)失效,鎖定太多的數(shù)據(jù)造成阻塞,嚴(yán)重影響效率。

Undo logo事務(wù)日志性能問(wèn)題

容易造成Undo logo日志數(shù)據(jù)量很大,降低了日志的查詢性能,包括對(duì)事務(wù)的回滾效率也會(huì)降低。

并發(fā)數(shù)據(jù)庫(kù)壓力太大

并發(fā)量達(dá)到一定程度,會(huì)對(duì)數(shù)據(jù)庫(kù)讀寫造成不小的壓力,會(huì)堆積大量等待線程。

如何優(yōu)化大事務(wù)

事務(wù)里面不要進(jìn)行遠(yuǎn)程RPC調(diào)用

首先事務(wù)里面進(jìn)行遠(yuǎn)程的接口調(diào)用,如果不采用分布式事務(wù)框架,本身就會(huì)存在事務(wù)不一致的情況,無(wú)法進(jìn)行數(shù)據(jù)的回滾操作,并發(fā)情況下遠(yuǎn)程服務(wù)響應(yīng)不及時(shí),會(huì)出現(xiàn)接口返回不一致問(wèn)題,當(dāng)然必須采用異步調(diào)用,后面會(huì)提到。

編程型事務(wù)更加靈活

聲明式事務(wù)只需要加在方法頭加@Transactional注解即可開(kāi)啟事務(wù),但是還是不太靈活,意味著整個(gè)方法所進(jìn)行對(duì)數(shù)據(jù)庫(kù)操作都要加進(jìn)事務(wù),當(dāng)然一次查詢也要進(jìn)入事務(wù),這并不是我們想要的,我們?cè)趗pdate、insert操作上進(jìn)行事務(wù)操作,方便進(jìn)行回滾。

public Boolean transactionCommit(String userName) {
    //查詢用戶
    SysUser sysUser = userMapper.selectUserByUserName(userName,null);

    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
            try {
                if (null != sysUser) {
                    //用戶信息狀態(tài)更新 status更新為1
                    userMapper.updateStatus(userName);
                }
            } catch (Exception e){
                //回滾
                transactionStatus.setRollbackOnly();
            }
        }
    });
    //再次查詢
    SysUser sysUser1 = userMapper.selectUserByUserName(userName,"1");
    /log/.info("狀態(tài)為1的用戶信息"+JSON./toJSONString/(sysUser1));
    return  true;
}

編程式事務(wù)的靈活點(diǎn)在于可以控制事務(wù)執(zhí)行方法,運(yùn)用transactionTemplate類進(jìn)行事務(wù)操作,查詢操作可以寫在外面,這樣查詢獲取數(shù)據(jù)的操作就不會(huì)進(jìn)入mysql事務(wù)表。

數(shù)據(jù)分批處理

對(duì)于事務(wù)的更新或者插入,前端可能會(huì)有批量操作,大規(guī)模數(shù)據(jù)的批量更新、插入也會(huì)對(duì)事務(wù)接口產(chǎn)生影響,一旦其中有更新或插入失敗,為了保證事務(wù)的一致性,整個(gè)操作都要進(jìn)行回滾;

  • 前端:可以限制數(shù)據(jù),對(duì)后端接口的訪問(wèn),可以將數(shù)據(jù)進(jìn)行分頁(yè),多次請(qǐng)求,可以避免事務(wù)提交大量數(shù)據(jù)。
  • 后端:也可以去數(shù)據(jù)進(jìn)行分頁(yè)處理,例如每次可以限制50條進(jìn)行操作,如果是新增邏輯,使用Mybatis的批量更新大大提升效率
List> partition = Lists.partition(receivableFeeSaveDTOList, 50);

大事務(wù)拆分小事務(wù)

可以將一個(gè)事務(wù)接口,拆分成多個(gè)事務(wù)接口,并且每個(gè)事務(wù)接口只做一件事,比如上面的收款單生成接口,金額回寫、第三方接口調(diào)用、調(diào)用后的結(jié)果回寫都可以抽成一個(gè)哥小事務(wù)接口。

就好比做一件很復(fù)雜的事情,咋一眼看上去很復(fù)雜,但是我們把這復(fù)雜的步驟,進(jìn)行多個(gè)步驟的拆分,每個(gè)階段完成每個(gè)階段的事情,就可以將整個(gè)過(guò)程簡(jiǎn)化,看起來(lái)就沒(méi)那么復(fù)雜了。

異步并行處理

重中之重,事務(wù)里如果無(wú)法避免遠(yuǎn)程調(diào)用,那么肯定是需要進(jìn)行異步調(diào)用,因?yàn)闊o(wú)法保證遠(yuǎn)程接口的及時(shí)響應(yīng)性,CompletableFuture異步編排特性可以用到,task1和task2任務(wù)結(jié)束后,執(zhí)行task3。

CompletableFuture task1 =CompletableFuture.supplyAsync(() -> {
    System.out.println("單號(hào)check線程" + Thread.currentThread().getId());
    //單號(hào)check接口 校驗(yàn)失敗拋出異常

    return "賬單實(shí)體信息";
}, executor);
CompletableFuture task2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("收款單生成線程" + Thread.currentThread().getId());
    try {
        //收款單生成

        return “賬單編號(hào)”;
        Thread.sleep(3000);
        System.out.println("任務(wù)2結(jié)束:");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}, executor);

 //task1、task2 執(zhí)行完執(zhí)行task3 ,需要感知task1和task2的執(zhí)行結(jié)果
CompletableFuture future = task1.thenCombineAsync(task2, (t1, t2) -> {

    System.out.println("賬單金額回寫線程" + Thread.currentThread().getId());
    // t1 、t2返回判斷

    //回寫返回結(jié)果
    return ture;
}, executor);

總結(jié)

可見(jiàn)大事務(wù)是我們接口效率低下的罪魁禍?zhǔn)?,有時(shí)候我們?yōu)榱丝焖賹?shí)現(xiàn)功能,可能會(huì)忽略一些關(guān)乎于性能的東西,而這些東西是我們能力提升的一個(gè)契機(jī)。


文章名稱:接口中的大事務(wù),該如何進(jìn)行優(yōu)化?
文章網(wǎng)址:http://www.5511xx.com/article/djoojhc.html