PDO :: ATTR_AUTOCOMMIT忽略非事务性INSERT / UPDATE

时间:2010-11-01 20:13:27

标签: php pdo

一直在摸不着头脑......

我有一个带pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0);的PDO对象,因为我想将FOR UPDATE与一些InnoDB表一起使用。阅读MySQL文档,FOR UPDATE只会在以下情况下锁定读取行:

  1. 您正在进行交易
  2. 您在交易中且已发出set autocommit=0
  3. 所以,我使用ATTR_AUTOCOMMIT来允许PDO对象锁定行。在任何一种情况下,这都会导致INSERT和UPDATE语句不适用。这些语句与FOR UPDATE无关,它们只是使用预准备语句运行在同一个PDO对象中。

    我的MySQL查询日志如下:

    xxx    Connect   user@host
    xxx    Query     set autocommit=0
    xxx    Query     INSERT INTO foo_tbl (bar, baz) VALUES ('hello','world')
    xxx    Quit
    

    PHP / PDO没有抱怨,但从表中选择表明数据尚未写入。

    我正在运行的查询已经运行了数千次;仅进行了ATTR_AUTOCOMMIT更改。删除该选项会使一切都恢复正常。使用选项autocommit=0,交易也正常。

    是否需要对PDO对象进行额外的调用(commit()正确地抱怨它不在事务中)才能使更改成为可能?基本上,我想要一个普通的PDO对象,但是可以选择锁定InnoDB表的事务之外的行(背景为什么这里太长而且很无聊)。

    我确信这是一件让我感到愚蠢的事情划伤头

1 个答案:

答案 0 :(得分:7)

    $db = new PDO('mysql:dbname=test');
    $db->setAttribute(PDO::ATTR_AUTOCOMMIT,0);
    var_dump($db->query('SELECT @@autocommit')->fetchAll()); //OK
    $db->query("INSERT INTO foo (bar) VALUES ('a');");
    $db->query("COMMIT;");//do by SQL rather then by interface / PDO-method

但实际上,你处于一个事务中(你还没有用PDO启动它),还是可以使用回滚等。这是否是一个错误(无法直接调用commit())是值得商榷的。