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