← 返回错误码列表

MySQL错误码 1205 分析与解决方案

错误信息

Error 1205

锁等待超时;尝试重启事务。

你的PHP应用在使用PDO连接MySQL时遇到了锁等待超时问题:

'pdo_code' => 'HY000',
'db_code' => 1205,
'db_error' => 'Lock wait timeout exceeded; try restarting transaction'

解决方案

  • 优化长时间运行的事务,尽快提交
  • 增加innodb_lock_wait_timeout参数值
  • 检查并终止长时间运行的事务
  • 优化查询性能,减少锁持有时间
  • 使用SHOW PROCESSLIST查找阻塞进程
  • 考虑使用READ COMMITTED隔离级别

PHP处理示例代码

// 处理锁等待超时错误
try {
  $pdo->beginTransaction();
  // 执行数据库操作...
  // UPDATE large_table SET ... WHERE ...
  $pdo->commit();
} catch (PDOException $e) {
  if ($e->getCode() == 'HY000' && strpos($e->getMessage(), '1205') !== false) {
    // 锁等待超时错误
    if ($pdo->inTransaction()) {
      $pdo->rollBack();
    }
    // 记录错误或通知用户
    error_log("锁等待超时: " . $e->getMessage());
    // 可以选择重试或返回错误信息
    throw new Exception("操作超时,请稍后重试");
  } else {
    // 其他错误,重新抛出
    throw $e;
  }
}

锁等待超时模拟演示

锁等待超时通常发生在一个事务等待另一个事务释放锁时:

事务 A (长时间运行)

1. 开始事务并更新 大表数据 (持有锁)

2. 执行复杂计算或等待用户输入...

3. 长时间不提交事务

事务 B (等待锁)

1. 尝试更新相同的 大表数据

2. 等待事务A释放锁...

3. 等待时间超过innodb_lock_wait_timeout

MySQL检测到超时

自动回滚事务B的操作

事务B将收到错误:1205

事务A继续正常运行

预防措施

1. 应用层优化

  • 保持事务简短,尽快提交
  • 避免在事务中进行复杂计算
  • 实现适当的错误处理和重试机制
  • 监控长时间运行的事务

2. 数据库层配置

  • 调整innodb_lock_wait_timeout参数(默认50秒)
  • 优化查询性能和索引
  • 使用READ COMMITTED隔离级别减少锁竞争
  • 定期分析并终止长时间运行的事务

3. 架构层优化

  • 将大表拆分为多个小表
  • 使用读写分离架构
  • 考虑使用消息队列处理批量操作
  • 实施连接池和资源限制

调试工具

使用以下MySQL命令分析锁等待问题:

# 查看当前运行的事务和锁信息
SHOW ENGINE INNODB STATUS;

# 查看当前连接和进程
SHOW PROCESSLIST;

# 查看InnoDB状态信息
SHOW STATUS LIKE 'innodb_row_lock%';

# 查看锁等待超时设置
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';

问题分析要点

在SHOW ENGINE INNODB STATUS输出中关注:

  • TRANSACTIONS 部分查看活动事务
  • LATEST DETECTED DEADLOCK 排除死锁
  • 查找长时间运行的事务和锁等待
  • 分析阻塞关系链