mvn test 運行多個測試時出現:InnoDB 行級鎖:共享鎖(S,SELECT ... LOCK IN SHARE MODE)與排他鎖(X,UPDATE/DELETE)。
死鎖場景:
-- 客戶端 A
START TRANSACTION;
SELECT * FROM blog WHERE id = 12 LOCK IN SHARE MODE; -- 持有 S 鎖
-- 客戶端 B
START TRANSACTION;
DELETE FROM blog WHERE id = 12; -- 需要 X 鎖,阻塞等待
-- 客戶端 A 繼續
DELETE FROM blog WHERE id = 12; -- 請求 X 鎖,觸發死鎖檢測
-- 客戶端 B 報錯:ERROR 1213 (40001): Deadlock found
單元測試中,前一個測試開啟事務未提交(@Transactional 未回滾或手動管理事務未 commit),導致鎖持有不釋放,後續測試觸發死鎖。
@Transactional 並設置 rollback = true(預設)commit() 或 rollback()DEBUG [PooledDataSource] - Waiting as long as 20000 milliseconds for connection.
MyBatis 預設 POOLED 數據源配置:
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
PooledDataSource 核心邏輯:
poolMaximumActiveConnections = 10(預設)poolTimeToWait = 20000ms測試用例未正確關閉 SqlSession,導致連接未歸還池中。併發測試時迅速耗盡 10 個連接。
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
// 執行操作
} // 自動關閉,歸還連接
<dataSource type="POOLED">
<property name="poolMaximumActiveConnections" value="50"/>
<property name="poolMaximumIdleConnections" value="20"/>
<property name="poolTimeToWait" value="10000"/>
</dataSource>
SHOW ENGINE INNODB STATUS 分析死鎖,VisualVM 監控連接池狀態