Spring單事務多線程操作引來的問題(Lock wait timeout exceeded; try restarting transaction)


1、場景描述

今天開發中遇到一個場景,在一個事務中的操作邏輯是:需要先刪除A表的某個記錄,然后多線程往A表里插入多條數據。

begin

delete from A where age=2;

以下多線程操作>>>

insert into A valus(5);

......

insert into A valus(5);

<<<

commit;

但是這樣操作會會導致delete from A where age=2;執行完后,后續的插入獲取鎖超時,從而導致整個事務的失敗回滾。

出現:Error updating database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

2、問題分析(結合本人真實業務代碼分析)

核心代碼

 

 

問題分析

  • applicationDirMapper.deleteByExample(exampleQuery);

    這段代碼執行后會在當前事務發起索引表效應。因為當前delete后面跟的條件字段applicationId他不是一個主鍵或者普通索引,所以會導致鎖表。

  • applicationServerDTO.getFolders().parallelStream().forEach(dirId -> {
      ApplicationDir applicationDir = new ApplicationDir();
      applicationDir.setApplicationId(applicationServer.getId());
      applicationDir.setDirId(dirId);
      applicationDirMapper.insertSelective(applicationDir);
    });

    這段代碼分析parallelStream是一個多線程操作。Spring這時候會給這里的每個線程分配一個共享的SqlSession,為什么確定說分配了一個新的SqlSession呢?我們以日志來證明。

    這個代碼實際可以看成里面有5個過程。

    第1步:80行是個查詢操作

    第2步:82行是個更新操作

    第3步:93行是個查詢操作

    第4步:94行是個刪除操作

    第5步:95行是個多線程插入操作

從1-5這5個步驟,如果再Spring單事務中沒有出現多線程的話1-5的操作的SqlSession他是相同的,不會一個操作創建一個SqlSession的,這也是為什么Spring保證事務的條件,因為全局的一個SqlSession我們才可以全局的去控制當前事務的原子性,要不全部提交成功要不全部失敗回滾。好了那我們怎么看出當前我們這個場景他就脫離了當前事務的SqlSession呢?看一下日志,本地開發真實輸出的日志。先上個局部圖,又有日志過多,后面會以文本的形式給大家把日志核心完整的展示出來。

 

 

 從上面的日志可以看出來過了第4步之后Spring就重新又Creating a new SqlSession了,導致后面的多線程里操作數據庫的SqlSession和當前事務中的SqlSession脫離了,多線程脫軌到另外一個獨立的事務中去了。

 當前事務的SqlSession

org.apache.ibatis.session.defaults.DefaultSqlSession@7aac05e2

多線程事務的SqlSession

org.apache.ibatis.session.defaults.DefaultSqlSession@2337080f

 由此可見由於當前事務第4步刪除操作導致鎖表,但是多線程的插入操作有獲取不到當前事務的鎖而當前事務被阻塞無法釋放鎖,導致多線程獲取鎖超時永遠等待中所以超時出現Lock wait timeout exceeded; try restarting transaction。

3、解決方案

a. 如果當前操作沒有書屋要求可以去掉@Transactional,這樣事務就可以自動提交不會導致鎖的獲取超時。

b.可以將多線程里面的代碼塊抽離出來通過異步消息去處理。

c.大家有什么好的想法可以幫忙指導一下。

 

 

4、總結問題

 開發中需要了解mysqld的鎖的類型,鎖的原理,鎖的算法,事務的隔離級別,事務的傳播屬性這樣才能更安全的介入開發中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM