Rocketmq消费消息时报错:
[org.springframework.beans.factory.xml.XmlBeanDefinitionReader] [INFO] - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
Consumer端消息消费延时,甚至丢失部分消息,起初以为是mybatis中sql语句错了。查了一遍发现没什么问题!
突然报这个错,郁闷了半天。还好配置了log4j,定位到了comsumer调用mapper执行update语句时卡住了。
想到一个取巧的办法,在调用的这句,加上try catch ,打印错误日志到控制台,一下就看出了问题所在。
logger.info("消费端接收成功!"+itemId+" "+amount);
try {
itemDOMapper.updateStock(itemId, amount);
}catch (Exception e){
logger.error(e);
}
logger.info("消费成功!");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
2019-07-26-16-04 [ConsumeMessageThread_2] [com.boge.demo.mq.MqConsumer] [ERROR] - org.springframework.dao.DeadlockLoserDataAccessException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: update item set stocknum = stocknum-? where id = ?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; ]; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transactio
原来是在update前,该行记录被其他事务锁定,导致update竞争锁失败,rocketmq的延时机制,不断的重复执行消费动作。导致部分消息延时甚至丢失。
解决办法:1、把事务和这条更新语句做一下调整,使更新执行时不受事务影响。
2、或者将需要更新的字段,放在不同的表中,这样事务的执行和某些字段的更新相互独立,互不影响。