錯誤信息如下:
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不配置事務,即修改方法名稱。