当连接在没有提交或回滚的情况下关闭时,mysqli 事务会发生什么?
What happens to a mysqli transaction when the connection is closed without a commit or rollback?
相关问题,但不是我想知道的,因为我很好奇 PHP mysqli
lib/functions:[=16= 的具体行为]
- What happens when a connection is closed mid-transaction?
- What happens to an uncommitted transaction when the connection is closed?
假设我有这样的代码(不管它是好是坏):
# ... some code
$conn = new mysqli('localhost', 'widget-manager', 'secret-widgets', 'widgets');
$conn->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
if (false) {
$sql = "UPDATE widgets SET widget_num = 1 WHERE widget_id = 5";
$res = $conn->query($sql);
if ($res) {
$conn->commit();
} else {
$conn->rollback();
}
}
$conn->close();
# ... some more code
将跳过包含提交和回滚的 if
,并且 mysqli
连接将在事务开始后但在调用提交或回滚之前关闭。
事务是否也会立即 destroyed/ended/whatever-the-proper-term,还是会保留并可能阻止来自其他服务的其他查询?
如果客户端断开连接,MySQL 服务器会清理会话。这将回滚任何未提交的事务、释放行锁和 table 锁、删除临时 table 和会话变量等
使用哪个客户端接口没有区别(mysqli vs. PDO vs. Java vs. 任何东西)。
当您调用 begin_transaction()
或将 autocommit
值设置为 0 时,您实际上是在告诉 MySQL 服务器 “在我明确表示之前不要提交数据告诉你。当您编写从不调用提交的代码时,服务器上的数据将永远不会提交。
当你调用mysqli::close()
或如果PHP脚本结束,那么mysqlnd(或libmysql)将发送COM_QUIT
命令到服务器。然后服务器将关闭会话并丢弃与其相关的任何数据,包括打开的事务、锁或准备好的语句句柄。 MySQL 服务器还应遵循 wait_timeout
设置,以防 PHP 脚本崩溃并且命令永远不会发送。
mysqli 特有的一件事是持久连接。这些连接在 PHP 次执行之间重复使用。它们通常被认为是搬起石头砸自己脚的好方法,这就是为什么 mysqli 有一些逻辑来帮助解决这个问题。您可以使用名为 rollback_on_cached_plink
的 INI 设置来指示 mysqli 在脚本结束时通过发出回滚命令来清理持久连接。
相关问题,但不是我想知道的,因为我很好奇 PHP mysqli
lib/functions:[=16= 的具体行为]
- What happens when a connection is closed mid-transaction?
- What happens to an uncommitted transaction when the connection is closed?
假设我有这样的代码(不管它是好是坏):
# ... some code
$conn = new mysqli('localhost', 'widget-manager', 'secret-widgets', 'widgets');
$conn->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
if (false) {
$sql = "UPDATE widgets SET widget_num = 1 WHERE widget_id = 5";
$res = $conn->query($sql);
if ($res) {
$conn->commit();
} else {
$conn->rollback();
}
}
$conn->close();
# ... some more code
将跳过包含提交和回滚的 if
,并且 mysqli
连接将在事务开始后但在调用提交或回滚之前关闭。
事务是否也会立即 destroyed/ended/whatever-the-proper-term,还是会保留并可能阻止来自其他服务的其他查询?
如果客户端断开连接,MySQL 服务器会清理会话。这将回滚任何未提交的事务、释放行锁和 table 锁、删除临时 table 和会话变量等
使用哪个客户端接口没有区别(mysqli vs. PDO vs. Java vs. 任何东西)。
当您调用 begin_transaction()
或将 autocommit
值设置为 0 时,您实际上是在告诉 MySQL 服务器 “在我明确表示之前不要提交数据告诉你。当您编写从不调用提交的代码时,服务器上的数据将永远不会提交。
当你调用mysqli::close()
或如果PHP脚本结束,那么mysqlnd(或libmysql)将发送COM_QUIT
命令到服务器。然后服务器将关闭会话并丢弃与其相关的任何数据,包括打开的事务、锁或准备好的语句句柄。 MySQL 服务器还应遵循 wait_timeout
设置,以防 PHP 脚本崩溃并且命令永远不会发送。
mysqli 特有的一件事是持久连接。这些连接在 PHP 次执行之间重复使用。它们通常被认为是搬起石头砸自己脚的好方法,这就是为什么 mysqli 有一些逻辑来帮助解决这个问题。您可以使用名为 rollback_on_cached_plink
的 INI 设置来指示 mysqli 在脚本结束时通过发出回滚命令来清理持久连接。