java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

在開發測試過程當中發現出了這個問題:前端

RECHARGE:業務,數據: {"platformUserNo":"RPD_1512632756191","amount":6000,"rechargeWay":"SWIFT","bankcode":"ICBK","payCompany":"LANMAO","payMobile":"13428284220","transactionTime":"20171228154506","rechargeStatus":"SUCCESS","commission":0,"requestNo":"20171228154433","code":"0","status":"SUCCESS"} 。回調處理異常--》
org.springframework.dao.CannotAcquireLockException: Hibernate operation: Could not execute JDBC batch update; SQL [update recharge set orderNum=?, pIpsBillNo=?, pay_company=?, reAccount=?, rechargeAmount=?, status=?, time=? where id=?]; Lock wait timeout exceeded; try restarting transaction; nested exception is java.sql.BatchUpdateException: Lock wait timeout exceeded; try restarting transaction
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:265)

Caused by: java.sql.BatchUpdateException: Lock wait timeout exceeded; try restarting transaction
	at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2054)
	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1467)
	at com.p6spy.engine.wrapper.StatementWrapper.executeBatch(StatementWrapper.java:98)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
	... 134 more
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
	at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2006)

其實也就 是 業務執行失敗了, 事務 不能提交。 能夠看到是 update 出現問題了。 百度了一下 , 都是 數據庫 死鎖了, 樂觀鎖什麼的java

開始是 覺得程序出現 死循環了, 但是看了一下其實並非。 而後 測試的時候,發現有時候 能夠,有時候又不行。 後來經過 打印日誌 才知道緣由。 原來是 重複執行的問題。 確實 在業務處理裏面使用到了 樂觀鎖。程序同步鎖。等,業務是有點複雜。 也就是前端 form 表單 重複提交了,甚至提交了屢次。。。 因此 由於 一個事務裏面 涉及到了多張表,而 多個線程一塊兒執行這個方法的時候, 就會出現 數據庫死鎖的問題。 每一個線程 鎖住了 一張表某行,而 想要 獲取 其餘線程鎖住的表某行數據的 鎖進行更新 , 因此就出現 互相等待。。。直到 事務 超時。。。mysql

這種狀況,特別是 和 第三方平臺進行對接業務的時候,好比直連請求,同步回調啊,異步回調啊,,, 都是有可能重複 接收的。 就算 發送 也是有可能重複發送的。 鑑別 是否重複響應,請求仍是 有必定的必要性的spring

相關文章
相關標籤/搜索