当前位置: 代码迷 >> 综合 >> 【Database】Mysql更新数据库操作时产生的死锁问题(Deadlock found...)
  详细解决方案

【Database】Mysql更新数据库操作时产生的死锁问题(Deadlock found...)

热度:37   发布时间:2023-12-17 17:34:48.0

Mysql更新数据库操作时产生的死锁问题(Deadlock found…)

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to…

产生问题代码

MybatisPlus的写法,.eq类似于Where后的语句。

@Overridepublic void updateProgrammeUser(Long userId, String externalNameKey, Long programmeId,String externalProgrammeKey, String externalKey, String status) {
    UpdateWrapper<ExternalProgrammeUserModel> updateWrapper = new UpdateWrapper<>();updateWrapper.lambda().set(ExternalProgrammeUserModel::getStatus, Constant.External.SUCCESS).set(ExternalProgrammeUserModel::getExternalProgrammePrimaryKey, externalProgrammeKey).set(ExternalProgrammeUserModel::getExternalUserPrimaryKey, externalNameKey).eq(ExternalProgrammeUserModel::getExternalKey, externalKey).eq(ExternalProgrammeUserModel::getInternalUserId, userId).eq(ExternalProgrammeUserModel::getInternalProgbaseMapper.update(null, updateWrapper);}

场景描述:

5个类以异步的方式调用此方法,更新同一张表。

可能产生的原因

  1. where后面的字段没有加索引
  2. (以上面代码举例)想当然的为where后的每一个字段加上索引,此时认为后面三个字段可以确定同一行,认为只锁住了一行。

其实行锁是对索引加锁,那么当where语句中包含多个条件时候,mysql在执行时也只用到了区分度最大的字段,所以实际上只使用了一个字段的索引,那么根据这个字段进行过滤出来的记录数可能就不止一条,也就是锁住了本不该锁住的行。

解决方案

使用联合索引(以上面代码举例),在数据库添加external_key,internal_user_id,internal_programme_id三个字段的联合索引。

alter table muses_external_programme_user add index update_test_index(external_key,internal_user_id,internal_programme_id);
  相关解决方案