簡體   English   中英

Spring Transactional 減慢了整個流程

[英]Spring Transactional slows down complete process

我正在嘗試分析我有兩個班級的情況。 一類是 ProcessImpl,它是起點並在內部調用其他子事務。我不知道出了什么問題。 processImpl 正在導入一些東西並將相關數據寫入數據庫。

眼鏡

Spring-orm 版本:3.2.18.RELEASE。

JDK 版本:1.8。

Db : H2(在任何 db 上記錄相同的性能)。

問題

如果我從ProcessImpl.processStage()刪除@Transactional ,則該過程需要約 50 秒如果我從ProcessImpl.processStage()保留@Transactional ,則該過程需要約 15 分鍾 不知道為什么會這樣。 長期以來,我一直試圖解決這個問題,但沒有運氣。 請看下面的代碼。

要求:完整的processStage()應該完成或完全回滾,即使其中一個子事務失敗。

僅供參考:我也收到很多消息,例如:“參與現有交易”。 試圖通過向processStage()添加propagation=Propagation.NESTED來解決這個問題,但沒有奏效。

ProcessImpl 類。

public class ProcessImpl {

    /*This is the big transaction that calls other transactional stuff from MyServiceImpl
    * This is starting point you can say for the process...
    * 
    * If we remove @Transactional from here the process is lightning fast 
    * With transactional : 15minutes
    * Without transactional : 50 seconds
    * */
    @Transactional
    public void processStage(){
        MyServiceImpl mp = new MyServiceImpl();
        //do some stuff
        mp.doWork1();

        //do more work
        mp.doWork2();

    }

}

MyServiceImpl 類

class MyServiceImpl{

    @Transactional
    public void doWork1(){
        Object o = doChildWork();
        // and more stuff
        //calls other class services and dao layers
    }

    @Transactional
    public void doWork2(){
        //some stuff
        doChildWork2();
        doChildWork();
        //more work
    }

    @Transactional
    public Object doChildWork(){
        return new Object(); //hypothetical, I am returning list and other collection stuff
    }

    @Transactional
    public Object doChildWork2(){
        return new Object(); //hypothetical, I am returning list and other collection stuff
    }

}

另外,在這里我會遇到自調用問題,這在事務中是不可取的嗎?

很難猜測你的代碼到底發生了什么,但是這些是可能的問題:

鎖定數據庫級別。 當您在doWork1()doWork2()更新相同的 DB 對象時,可能會發生這種情況。 由於這兩種方法都是一個事務中進行內部完成更新doWork1()將不會被提交到doWork2()完成。 這兩種方法可能會嘗試鎖定同一個 DB 對象並等待它。 從技術上講,它可以是任何 DB 對象:表中的行、索引、整個表等。

分析您的代碼並嘗試找出可能被鎖定的內容。 您還可以在方法運行時查看數據庫事務日志。 所有流行的 DB 都提供有助於查找有問題的地方的功能。

在休眠上下文刷新期間減慢速度。 如果您更新太多對象,ORM 引擎(比如 Hibernate)必須接收它們並將它們保存在內存中。 從字面上看,Hibernate 必須具有更新對象的所有舊狀態和所有新狀態。 有時它不是以最佳方式做到這一點。

您可以使用調試來指示這一點。 嘗試找到最慢的地方並檢查那里到底調用了什么。 我可能猜測它在休眠更新緩存狀態時會變慢。

還有一個問題。 我看到您在processStage()期間使用構造函數創建了MyServiceImpl 我建議您通過彈簧自動裝配替換此代碼。 首先,您使用它的方式不是它設計的使用方式,但理論上這也會以某種方式影響執行。

我會遇到自調用問題,這在事務中是不可取的嗎?

不,它會很好地忽略所有注釋。 的通話doChildWork()doChildWork2()doWork2()將被視為標准的java調用(春風不能夠任何“神奇”添加到他們,只要你直接調用它們)。

這里的任何答案實際上都只是(消息靈通的)猜想。 在這種情況下,最好的辦法是使用 Java 分析器並進行詳細的 cpu 級別分析以准確了解發生了什么。

我建議使用優秀的 YourKit,它是商業版,但您可以獲得免費試用版。

https://www.yourkit.com/docs/java/help/performance_bottlenecks.jsp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM