org.springframework.dao.CannotAcquireLockException異常分析

錯誤信息如下:

2017-09-27 16:27:16.153 - 【com.ldyun.base.service.impl.BaseRetailOrderServiceImpl】 - 新增零售商品訂單~org.springframework.dao.CannotAcquireLockException: 
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
### The error may involve com.ldyun.retail.mapper.RetailGoodsMapper.updateBySql-Inline
### The error occurred while setting parameters
### SQL: update retail_goods  SET stocks = stocks - CASE id  WHEN 83 THEN 1  END,saleCount = saleCount + CASE id  WHEN 83 THEN 1  END WHERE id IN (83)
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
; SQL []; Lock wait timeout exceeded; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction~
經過網上資料查詢,原因爲:Spring 事務嵌套造成死鎖。

經覈實代碼的確是service裏面調用service,且兩個service都配置了事務。頂層service名稱爲addRetailOrder,內層service名稱爲updateBysql。

事務配置爲:

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
			<tx:method name="del*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
			<tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
			<tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
			<tx:method name="try*" propagation="REQUIRED" read-only="false" rollback-for="com.wm.base.exception.TransactionRollbackException" />
		</tx:attributes>
	</tx:advice>
解決方法爲:

1、內層service實現方法配置@Transactional(propagation=Propagation.SUPPORTS)

	@Override
	@Transactional(propagation=Propagation.SUPPORTS)
	public int updateBySql(String sql) {
		// TODO Auto-generated method stub
		return retailGoodsDao.updateBySql(sql);
	}
2、外層service不配置事務,即修改方法名稱。

發佈了169 篇原創文章 · 獲贊 62 · 訪問量 77萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章