关于php8:PHP8体验pdomysql-事务提交失败

产生了什么
周末无事,想装上 PHP8 体验一把新版本的个性,找了一个 Yii2 写的老我的项目,后果运行 migration 初始化环境就遇到了问题,建表脚本间接报错。

Exception: There is no active transaction

而同样的脚本在 7.4 版本也齐全失常。

测试脚本

简化的脚本差不多是这样

$conn = new PDO("mysql:host=127.0.0.1;dbname=test", 'root', '123456');
 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 $conn->beginTransaction();
 try {
 $sql = "CREATE TABLE IF NOT EXISTS test (`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, `text` varchar(32) NOT NULL DEFAULT '', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
 $conn->exec($sql);
 
 $sql = "INSERT INTO test values(1,'test1')";
 $conn->exec($sql);
 
 $conn->commit();
 } catch (Exception $e) {
 echo $e->getMessage();
 $conn->rollBack();
 }

问题起因

MySQL DDL 语句会触发隐式提交,如果事务里执行的是其余 DML/DQL 语句,就齐全没问题。官网文档里也有提到这个问题。

Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.

然而在 PHP 8.0 以前的版本,带来的影响只是事务被提前提交,不能回滚而已,不晓得为啥 8.0 要改成一个异样,并且 ChangeLog 又并未提到该变更。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理