循环Db.update(sql,.....)抛出了死锁异常, 请问要怎么解决呢,先谢谢啦

异常如下:
com.jfinal.plugin.activerecord.ActiveRecordException: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
at com.jfinal.plugin.activerecord.DbPro.update(DbPro.java:283)
at com.jfinal.plugin.activerecord.Db.update(Db.java:206)
at com.tmbj.api.service.insure.TmInsureFenqiService$1.run(TmInsureFenqiService.java:1310)
at com.jfinal.plugin.activerecord.DbPro.tx(DbPro.java:694)
at com.jfinal.plugin.activerecord.DbPro.tx(DbPro.java:748)
at com.jfinal.plugin.activerecord.Db.tx(Db.java:460)
at com.tmbj.api.service.insure.TmInsureFenqiService.updateFenqiLineStateById(TmInsureFenqiService.java:1297)


    /**
     * 用户提交申请
     */
public  CommonResult updateFenqiLineStateById(Record record){
 CommonResult commonResult = new CommonResult();
 commonResult.setCodeAndMsg(Constant.SUCCESS_CODE, Constant.SUCCESS_MSG);
 String fenqiLineIds=record.get("fenqiLineIds");
 Long insureInfoId=record.getLong("insureInfoId");
 String[]fenqiLineIdsStr=fenqiLineIds.split(",");
 //默认待支付
 Integer state = 5;
 for (String fenqiLineId:fenqiLineIdsStr){
    Record lineRecord=Db.findById("tm_insure_fenqi_line",fenqiLineId);
    // 待审核
    if (lineRecord.getInt("insureType") == 1 || lineRecord.getInt("fenqi") == 1) {
        state = 3;
      }
 String sql="update tm_insure_fenqi_line t set t.state=?,t.modifyTime=?,t.modefier=? where id=?";
 int bCount= Db.update(sql,state,new Date(),insureInfoId.intValue(),fenqiLineId);
   if (bCount>0) {
    //修改成功调用推送方法
     ******************推送省略*************************
   } else {
    commonResult.setCodeAndMsg(ErrorCode.ERROR_CODE, "用户提交申请失败!");
   }
   ommonResult.setData(record);
   }
  return commonResult;
}


评论区

JFinal

2018-06-14 11:19

将引擎从 MyISAM 改成 InnoDB,可以解决很大部分问题

如果你的已然是 InnoDB,只能是从 sql 以及程序结构上去调整,数据库本身是无法杜绝所有死锁的,很多死锁数据库是让其失败然后释放锁来解决

wikilu

2018-06-14 15:17

@JFinal 谢谢老哥的热心解答,是我粗心了,已经解决,我的查询在循环操作里面,update也在循环里面,导致抢占锁的情况出现,我把查询放外面,查出List,然后再循环更新,就没有出现死锁的情况了

热门反馈

扫码入社