0

0

如何解决 PHP 脚本并发访问 MySQL 时表锁导致的服务器无响应问题

霞舞

霞舞

发布时间:2026-01-22 12:12:04

|

820人浏览过

|

来源于php中文网

原创

如何解决 PHP 脚本并发访问 MySQL 时表锁导致的服务器无响应问题

浏览器中同时运行多个 php 脚本时,因会话阻塞和隐式事务行为,可能导致 mysql 表级锁或连接排队,使其他请求长时间等待甚至超时;通过命令行执行耗时脚本可绕过 web 服务器会话限制,显著提升并发可用性。

该问题本质并非 MySQL 自身“锁表”(如 MyISAM 的表锁),而是由 PHP 的 Web 运行环境与数据库交互方式共同引发的并发瓶颈。虽然你使用的代码未显式开启事务,但以下关键因素在浏览器环境下叠加放大了阻塞效应:

? 根本原因分析

  1. PHP 会话阻塞(Session Locking)
    若两个脚本均调用 session_start()(即使未显式写出,某些框架或配置会自动启用),PHP 默认会对同一会话 ID 的后续请求进行串行化处理——即第二个请求必须等待第一个脚本释放会话文件锁。这是最常见却被忽视的原因,且与 MySQL 无关,却表现为“查询卡住”。

  2. 长连接 + 隐式事务行为(尤其 InnoDB)
    尽管你的 SELECT 和 UPDATE 语句未包裹在 BEGIN/COMMIT 中,InnoDB 在自动提交(autocommit=1)模式下仍为每条 DML 语句创建独立事务。但若脚本执行缓慢(如频繁网络爬虫),大量短事务叠加可能加剧锁竞争;更严重的是:若 UPDATE TableA 涉及非主键/非索引字段,可能触发间隙锁(Gap Lock)或临键锁(Next-Key Lock),导致其他 SELECT ... WHERE ... 查询被阻塞。

  3. Web 服务器资源限制
    Apache(MPM prefork)或 PHP-FPM 默认配置通常限制并发进程/线程数(如 max_children=5)。当脚本 1 占用一个 worker 长达数分钟,其余请求将排队等待,表现为“页面无响应”,实则是 HTTP 层超时而非数据库层死锁。

✅ 推荐解决方案(按优先级排序)

✅ 方案一:禁用会话或提前关闭(立即生效)

// Script 1 开头添加(若无需 session 数据)
if (session_status() === PHP_SESSION_ACTIVE) {
    session_write_close(); // 释放会话锁,允许其他请求并发进入
}
// 后续代码正常执行...

✅ 方案二:改用 CLI 模式执行(推荐长期方案)

# 终止浏览器触发,改用终端运行
php /var/www/html/crawl_script.php

CLI 模式无会话机制、无 Web 服务器 worker 限制、超时时间更宽松,是处理批量任务的标准实践。

如此AI员工
如此AI员工

国内首个全链路营销获客AI Agent

下载

✅ 方案三:优化数据库操作(治本之策)

  • 为 TableA 中 UPDATE 和 Script 2 的 WHERE 条件字段添加复合索引,避免全表扫描与锁升级;
  • 将循环内多次 UPDATE 改为批量更新(例如每 100 条合并为一条 INSERT ... ON DUPLICATE KEY UPDATE 或 UPDATE ... WHERE id IN (...));
  • 显式控制事务粒度:
    $conn->beginTransaction();
    try {
        // 批量处理逻辑
        $conn->commit();
    } catch (Exception $e) {
        $conn->rollback();
        throw $e;
    }

⚠️ 注意事项

  • 不要依赖 set_time_limit(0) 或 ignore_user_abort(true) 来“修复”阻塞——它们掩盖问题而非解决;
  • SELECT ... FOR UPDATE 或 LOCK IN SHARE MODE 等显式锁语句需谨慎使用,此处未出现,故排除;
  • 使用 SHOW PROCESSLIST; 和 SELECT * FROM information_schema.INNODB_TRX; 可实时诊断活跃事务与锁等待。

综上,优先检查并解除会话锁,再将长时任务迁移至 CLI 环境,并辅以数据库索引与批量操作优化——三者结合,即可彻底消除“脚本一运行,其他页面全部卡死”的现象。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2776

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1679

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1538

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

1015

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1464

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1255

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1569

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1307

2023.11.13

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.9万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 805人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号