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不配置事務,即修改方法名稱。


免責聲明!

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



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