phpEnv 不解决 MySQL 死锁,排查需结合 MySQL 层与 PHP 逻辑:先在控制面板配置文件中启用 innodb_print_all_deadlocks = ON 并重启 MySQL,再用 SHOW VARIABLES LIKE 'log_error' 查日志路径(如 C:\phpEnv\mysql\data\*.err),配合 SHOW ENGINE INNODB STATUS\G 查最近一次死锁,本地可模拟并发脚本复现并验证锁顺序、索引、事务范围等关键点。

phpEnv 本身不解决 MySQL 死锁,它只是本地开发环境套件;死锁排查和解决必须落在 MySQL 层 + PHP 应用逻辑上。
phpEnv 中怎么快速查到 MySQL 死锁日志
phpEnv 默认使用 MySQL 的 error log 记录死锁,但默认可能没开全量记录。先确认是否启用:
- 进 phpEnv 控制面板 → MySQL → “配置文件”(通常是
my.ini或my.cnf) - 检查是否有这行:
innodb_print_all_deadlocks = ON;没有就手动加上,重启 MySQL - 查日志路径:
SHOW VARIABLES LIKE 'log_error';,常见位置是C:\phpEnv\mysql\data\*.err - 别只看
SHOW ENGINE INNODB STATUS\G——它只保留最后一次死锁,而innodb_print_all_deadlocks = ON才能持续追查
在 phpEnv 里复现和验证死锁逻辑
本地环境的好处是可以可控地模拟并发场景,比如用两个 CLI 窗口同时跑 PHP 脚本:
- 确保事务隔离级别是默认的
REPEATABLE READ(InnoDB 默认),不是READ COMMITTED - 写两个脚本,分别执行不同顺序的更新:
UPDATE users SET name='a' WHERE id=1;和UPDATE orders SET status=2 WHERE user_id=1;,再反过来调换顺序 - 用
php -f script1.php和php -f script2.php同时触发,观察是否报错1213 Deadlock found when trying to get lock - 注意:phpEnv 的 MySQL 通常没开慢查询日志,如需分析锁等待链,得手动加
long_query_time = 1并开启slow_query_log
PHP 代码里怎么避免被 phpEnv 的 MySQL 触发死锁
本地环境容易忽略真实线上的锁行为差异,比如索引缺失、自动提交未关、事务包裹不全 —— 这些在 phpEnv 里一样会死锁:
立即学习“PHP免费学习笔记(深入)”;
-
DB::transaction()必须包裹整个“读-改-写”,不能只给selectForUpdate()加事务,否则锁立刻释放 - where 条件必须命中索引,否则
SELECT ... FOR UPDATE会升级成表锁——在 phpEnv 里建表时漏掉索引很常见 - 避免在事务里做
file_get_contents()、curl_exec()这类耗时操作,本地网络快,但锁持有时间仍被拉长 - Laravel 中慎用
updateOrCreate()套路:它内部是先SELECT再INSERT/UPDATE,若并发高且无唯一索引约束,极易和别的事务形成间隙锁冲突
真正容易被忽略的是:phpEnv 的 MySQL 配置常沿用最低要求,innodb_lock_wait_timeout 可能还是默认 50 秒,导致本地压测时卡住不报错,误以为没问题;上线后因超时短反而暴露死锁——务必同步调整这个值到 10~20 秒用于本地验证。



















