PHP Conference Japan 2024

mysqli::begin_transaction

mysqli_begin_transaction

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

mysqli::begin_transaction -- mysqli_begin_transaction启动事务

描述

面向对象风格

public mysqli::begin_transaction(int $flags = 0, ?string $name = null): bool

过程化风格

mysqli_begin_transaction(mysqli $mysql, int $flags = 0, ?string $name = null): bool

启动一个事务。需要 InnoDB 引擎(默认启用)。有关 MySQL 事务工作原理的更多详细信息,请参见 » https://dev.mysqlserver.cn/doc/mysql/en/commit.html

参数

mysql

仅过程化风格:由 mysqli_connect()mysqli_init() 返回的 mysqli 对象

flags

有效的标志是

name

事务的保存点名称。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 描述
8.0.0 name 现在可以为空。

示例

示例 #1 mysqli::begin_transaction() 示例

面向对象风格

<?php

/* 如果发生错误,则告诉 mysqli 抛出异常 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 表引擎必须支持事务 */
$mysqli->query("CREATE TABLE IF NOT EXISTS language (
Code text NOT NULL,
Speakers int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
);

/* 启动事务 */
$mysqli->begin_transaction();

try {
/* 插入一些值 */
$mysqli->query("INSERT INTO language(Code, Speakers) VALUES ('DE', 42000123)");

/* 尝试插入无效值 */
$language_code = 'FR';
$native_speakers = 'Unknown';
$stmt = $mysqli->prepare('INSERT INTO language(Code, Speakers) VALUES (?,?)');
$stmt->bind_param('ss', $language_code, $native_speakers);
$stmt->execute();

/* 如果代码在没有错误的情况下到达此处,则提交数据库中的数据 */
$mysqli->commit();
} catch (
mysqli_sql_exception $exception) {
$mysqli->rollback();

throw
$exception;
}

过程化风格

<?php

/* 如果发生错误,则告诉 mysqli 抛出异常 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$mysqli = mysqli_connect("localhost", "my_user", "my_password", "world");

/* 表引擎必须支持事务 */
mysqli_query($mysqli, "CREATE TABLE IF NOT EXISTS language (
Code text NOT NULL,
Speakers int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
);

/* 开始事务 */
mysqli_begin_transaction($mysqli);

try {
/* 插入一些值 */
mysqli_query($mysqli, "INSERT INTO language(Code, Speakers) VALUES ('DE', 42000123)");

/* 尝试插入无效值 */
$language_code = 'FR';
$native_speakers = 'Unknown';
$stmt = mysqli_prepare($mysqli, 'INSERT INTO language(Code, Speakers) VALUES (?,?)');
mysqli_stmt_bind_param($stmt, 'ss', $language_code, $native_speakers);
mysqli_stmt_execute($stmt);

/* 如果代码在没有错误的情况下到达此处,则提交数据库中的数据 */
mysqli_commit($mysqli);
} catch (
mysqli_sql_exception $exception) {
mysqli_rollback($mysqli);

throw
$exception;
}

注释

注意:

此函数不适用于非事务性表类型(如 MyISAM 或 ISAM)。

参见

添加注释

用户贡献的注释 2 条注释

Ral
6 年前
如果您收到类似以下的错误:“此服务器版本不支持“READ WRITE”和“READ ONLY”。需要最低 5.6.5 版本”以及确实支持它们的 MariaDB 版本,这是由于 mysqli 中的内部检查与 MariaDB 中允许与 Oracle MySQL 进行复制的黑客冲突。

例如,MariaDB 为其服务器版本号添加前缀“5.5.5-”,“5.5.5-10.3.7-MariaDB-1:10.3.7+maria~stretch”。这是因为 Oracle MySQL 会将“10”解释为版本 1。了解 MariaDB 的 MySQL 客户端已更新为检测并删除此前缀。

但是,mysqli.begin-transaction 的检查会看到 5.5.5 前缀,因此会失败。

解决方法是在命令行中使用 --version 选项为 MariaDB 指定一个没有前缀的自定义版本字符串。然后 mysqli.begin-transaction 函数按预期工作。
PHP 专家
4 年前
MySQL 5.6 引入了只读模式,该模式会对您的事务应用仅当它预先知道不会进行任何表修改并且不会发出任何锁时才能应用的优化。

在所有版本(包括 MySQL 5.6)中,默认访问模式都是读写。从 MySQL 5.7 开始,会自动检测适当的访问模式。因此,如果您的事务尝试修改表或锁定表,它将自动使用读写模式,否则它将使用只读模式,并且您的事务将受益于由此带来的优化,而无需显式声明为只读。

因此,您只需要在使用 MySQL 5.6 并确定需要只读模式时才需要显式声明访问模式。请注意,在只读模式下尝试修改表或发出锁的任何查询都将失败。仍然可以修改临时表。

(版主。此帖子应替换我之前在此主题上发布的帖子。谢谢。)
To Top