並發錯誤:事務(進程 ID )與另一個進程已被死鎖在 lock 資源上,且該事務已被選作死鎖犧牲品


這個是並發情況下導致的數據庫事務錯誤,先介紹下背景。

背景

springboot+springmvc+sqlserver+mybatis

一個controller里有五六個接口,這些接口都用到了spring的事務管理,這些接口單個調用的時候都很正常,當我模擬幾十個並發請求這些接口的時候,總會有一兩次的mybatis的持久化操作會出錯,具體錯誤:

nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.lang.reflect.UndeclaredThrowableException
### The error may involve com.xxxxxxxxx-Inline
### The error occurred while setting parameters
### SQL: update xxxx set ccccc = ?  ,jid = ? ,status = ?                                                                                         where bcode=? and status != 0
### Cause: java.lang.reflect.UndeclaredThrowableException

根據提示的這個UndeclaredThrowableException,到網上搜索都是說mybatis的映射文件里的字段屬性與model里的寫的不一致。

但是如果是寫法不對的話,應該每次請求的都報錯啊,現在是幾十次里只有一兩次報錯,肯定不是這個原因。

在網上搜了半天,無果,於是把代碼放到服務器上再模擬並發測試一下,還是會有一兩次報錯,不過這次報的錯就很明朗了

### Error querying database.  Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 事務(進程 ID 62)與另一個進程被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新運行該事務。
### The error may exist in file [E:\kkkkk\xxxMapper.xml]
### The error may involve com.xxxxx.ppppp
### The error occurred while handling results
### SQL: SELECT b.* FROM xxxxx a RIGHT JOIN ooooo b ON a.GId = b.id  where a.bcode = '11111'
### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 事務(進程 ID 62)與另一個進程被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新運行該事務。
; SQL []; 事務(進程 ID 62)與另一個進程被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新運行該事務。; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: 事務(進程 ID 62)與另一個進程被死鎖在 鎖 資源上,並且已被選作死鎖犧牲品。請重新運行該事務。

原來是並發引起的數據庫事務報錯,具體原因和修改看這篇:對於spring中事務@Transactional注解的理解

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我了解了一下事務處理機制,原來這個錯誤是在數據庫中拋出的。因為不同線程在事務中處理相同的數據時,數據庫會采取讓一個執行而另一個放棄執行,於是就出現上面的錯了。之所以插入不容易出現這個錯誤,是因為插入的速度快,不容易出現。同時如果修改的時候按照條件修改數據速度就會慢,如果按照主鍵或索引修改速度就會快,也不容易出現這個錯誤。@xmt1139057136,雖然沒給具體的方法確實是按照這個思路想出來的,謝謝啦。對了,我對TOMCAT在局域網內進行壓力測試時,發現速度明顯比本地慢的多,而且無法處理並發1000條了(本機是可以的),向請教一下。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解決方法

1.Spring異常重試框架Spring Retry

2.把事務的隔離級別改為寬松的,read_uncommited


免責聲明!

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



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