phpEnv中MySQL默认隔离级别为REPEATABLE READ,修改需区分会话级(SET SESSION)和全局级(my.ini配置+重启服务),且必须重连或重启才能生效;验证须用SELECT @@transaction_isolation而非控制面板显示。

phpEnv 是个本地开发环境套件,它打包的 MySQL 默认用的是 REPEATABLE READ 隔离级别,但你不能靠改 phpEnv 界面里的“配置文件”就让所有连接立刻生效——改完不重启服务、不重连客户端,SELECT @@transaction_isolation 依然显示旧值。
怎么确认当前连接实际用的隔离级别
别信 phpEnv 控制面板上写的“默认值”,得看真实运行时状态:
-
SELECT @@transaction_isolation—— 查当前会话级别(最准) -
SELECT @@global.transaction_isolation—— 查全局配置(只影响新连接) - 注意:
@@tx_isolation是旧版变量名,MySQL 5.7.20+ 已弃用,优先用@@transaction_isolation
会话级修改:PHP 代码里临时切级别
适合调试或特定业务逻辑需要(比如报表导出要避免幻读),不影响其他请求:
- 在 PDO 连接后、事务开始前执行:
$pdo->exec("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED") - MySQLi 同理:
$mysqli->query("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE") - 这个设置只对当前 PHP 请求生命周期有效,脚本结束即失效
- 不要在事务已开启(
BEGIN或START TRANSACTION)之后再设,MySQL 会报错ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress
全局级修改:让新连接默认用新级别
phpEnv 的 MySQL 配置文件路径通常是 phpEnv\mysql\my.ini(Windows)或 phpEnv/mysql/my.cnf(macOS/Linux),改这里才能持久生效:
立即学习“PHP免费学习笔记(深入)”;
- 在
[mysqld]段落下加一行:transaction-isolation = "READ-COMMITTED"(必须用短横线,推荐加英文双引号) - 改完必须重启 phpEnv 的 MySQL 服务,否则配置不加载
- 已存在的 PHP 连接(比如 Apache 子进程里复用的长连接)仍维持原隔离级别,只有新建立的连接才用新值
- 验证是否生效:重启后开新命令行,连 MySQL 执行
SELECT @@global.transaction_isolation,看是否为新值
为什么改了配置还是没效果?常见翻车点
这个问题几乎全出在“生效范围”理解偏差上:
- 执行
SET GLOBAL transaction_isolation = 'READ-COMMITTED'后,老 PHP-FPM 进程里的连接不会变——它们是在全局变量修改前建立的 - phpEnv 界面点“重启 MySQL”有时只 reload 配置,不一定真正 stop/start,建议手动进任务管理器或终端 kill mysqld 进程再启
- PDO 默认开启
autocommit=1,单条语句不是事务;想测隔离级别,必须显式BEGIN+ 多语句 +COMMIT/ROLLBACK,否则根本触发不了 MVCC 行为 -
READ UNCOMMITTED在 phpEnv 下虽能设,但 InnoDB 实际忽略部分锁行为,且极易引发脏读,线上和本地调试都建议跳过它
最常被忽略的一点:phpEnv 里多个项目可能共用一个 MySQL 实例,改全局隔离级别会影响所有项目。如果某个老系统依赖 REPEATABLE READ 的快照读语义(比如分页缓存逻辑),单独在代码里用 SET SESSION 切更安全。



















