【问题标题】:MySQLi API and how transactions work & commitMySQLi API 以及事务如何工作和提交
【发布时间】:2015-11-23 04:05:01
【问题描述】:

关于使用 PHP 的 API 支持 MySQL 事务,我想知道 autocommit

例如,我不确定默认情况下它是如何工作的,但理想情况下,我希望所有查询都自动提交 除非我明确地使用以下内容启动事务:

$db->begin_transaction();
$db->query(...);
$db->query(...);
$db->commit();

作为一个相关问题,我注意到 begin_transaction() 直到 PHP 5.5 才被引入,所以是否有可能在 5.5 之前获得行为?

我知道有$db->autocommit(),但这是否意味着如果我想要上述行为,我需要默认启用它,然后在任何交易之前执行$db->autocommit(false),然后在之后执行$db->autocommit(true)

【问题讨论】:

    标签: php mysql mysqli transactions


    【解决方案1】:

    这是交易的documentationautocommit 设置。

    引用该文档:

    默认情况下,MySQL 在启用自动提交模式的情况下运行。这意味着一旦您执行更新(修改)表的语句,MySQL 就会将更新存储在磁盘上以使其永久化。更改无法回滚。

    当我读到这篇文章时,它的工作方式是这样的:

    假设您在不使用事务的情况下进行查询。您使用 autocommit on 执行 INSERT 并且 INSERT 立即发生(即立即存储到磁盘)。 UPDATE?它立即发生。

    现在假设您关闭autocommit 并以相同的方式进行查询。上面的引用暗示如果您在关闭autocommit 的情况下执行INSERT 命令,它不会立即存储到磁盘。那么INSERT 会发生什么?再次引用文档:

    通过将 autocommit 变量设置为零来禁用自动提交模式后,对事务安全表(例如 InnoDB 或 NDBCLUSTER 的表)的更改不会立即永久生效。您必须使用 COMMIT 将更改存储到磁盘或使用 ROLLBACK 忽略更改。

    因此,简而言之,使用autocommit 是实现事务的另一种方式。在 MySQL 中,您可以这样做:

    START TRANSACTION;
    INSERT INTO table VALUES (1, 2, 3);
    COMMIT;
    

    或者你可以这样做:

    SET autocommit=0;
    INSERT INTO table VALUES (1, 2, 3);
    COMMIT;
    

    还要注意,当您更改 autocommit 值时,会有一个隐式提交 - 所以这样做是等效的:

    SET autocommit=0;
    INSERT INTO table VALUES (1, 2, 3);
    SET autocommit=1;
    

    您可以在 PHP 中以相同的方式执行操作,使用 $db->begin_transaction();$db->autocommit(false); 开始事务,最后使用 $db->commit();。就个人而言,我发现begin_transaction 方法更清晰。

    【讨论】:

    • 所以你说的是 autocommit 控制 all 查询,如果我希望查询不是由 begin_transaction 预先设置为自动提交,那么我需要设置 @987654341 @默认然后autocommit(false)在事务之前然后autocommit(true)在事务之后?如果是这样,那么begin_transaction 的目的是什么?
    • 按照我阅读 MySQL 文档的方式,BEGIN TRANSACTION 在 MySQL 服务器级别是 SET autocommit=0 的同义词,并且可以互换。 BEGIN TRANSACTIONCOMMIT 提供更多选项以更好地控制交易。 PHP begin_transactionautocommit(false) 方法可以互换吗?如果 PHP 只是包装 MySQL 语句,它们应该是。
    • begin_transaction 的目的是什么?好吧,据推测,它应该提供 MySQL 为BEGIN TRANSACTION 提供的一些附加选项,但documentation 非常稀疏 - 有一个警告说'这个函数目前没有记录;只有它的参数列表可用。 :-/
    • 好的,所以从你所说的情况来看,我需要确保 autocommit(true) 默认打开,然后只要我使用 BEGIN TRANSACTIONSET autocommit=0 开始交易我会很好;然后之后我必须做SET autocommit=1 才能重新打开它?如果是这样,我可能会创建一个类来包装这个功能。
    • 自动提交默认开启;您可以使用BEGIN TRANSACTION/COMMITSET autocommit=0/SET autocommit=1 来封装交易;我可能会使用前者,因为它对我来说似乎更清晰。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2013-07-13
    • 2012-05-22
    • 2012-08-01
    • 2016-11-19
    • 2021-09-12
    相关资源
    最近更新 更多