2010-11-01 44 views
7

被抓我在這頭一會兒....PDO :: ATTR_AUTOCOMMIT忽略非事務INSERT/UPDATE

我有一個pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0); PDO對象,因爲我想用FOR UPDATE一些InnoDB表。

  1. 你是在一個交易
  2. 你是不在事務set autocommit=0已發出

所以,我:閱讀MySQL的文檔,如果FOR UPDATE只鎖定讀取行使用ATTR_AUTOCOMMIT來允許PDO對象鎖定行。無論哪種情況,都會導致INSERT和UPDATE語句不適用。這些語句與FOR UPDATE無關,它們只是通過具有準備語句的相同PDO對象運行。

我的MySQL查詢日誌的樣子:

xxx Connect [email protected] 
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表交易外行選項(背景爲什麼過長而乏味這裏)。

我敢肯定,這是愚蠢的東西我失蹤劃痕頭

+0

別擔心,我們有時會錯過的事情!我知道它發生在我身上更喜歡比我承認:-) – Josh 2010-11-04 21:52:54

回答

6
$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開始吧),回滾等還是可用的。這是否是一個bug(不能直接調用commit())是有爭議的。

+0

+1 - 我會說這是一個錯誤......但是,嘿,談論borked PHP API時,有較高的優先級:P很好的回答。 – 2010-11-02 19:21:52

+0

這是不是一個錯誤,它只是一個誤導性的名字,因爲許多人鏈接詞「承諾」的交易。它並不意味着你未完成的交易會自動提交或不提交,它只是意味着你的查詢不是由交易啓動的,而是自動「提交」的,默認情況下它們是..技術上,如果它被禁用,你的連接開始一個交易。 – 2013-04-29 13:17:16