2010-11-01 21 views
7

estado rascándose la cabeza en esto por un tiempo ....PDO :: ATTR_AUTOCOMMIT ignora INSERT no transaccional/ACTUALIZACIÓN

Tengo un objeto de orden de pago pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0); como yo quiero usar FOR UPDATE con algunas tablas InnoDB. La lectura de la documentación de MySQL, FOR UPDATE solamente se bloqueará filas de lectura si:

  1. Usted está en una transacción
  2. Usted no está en una transacción y set autocommit=0 ha sido declarada

Por lo tanto, yo soy usando ATTR_AUTOCOMMIT para permitir que el objeto PDO bloquee filas. En cualquier caso, esto hace que las instrucciones INSERT y UPDATE no se apliquen. Estas declaraciones no tienen nada que ver con FOR UPDATE, solo están ejecutando el mismo objeto PDO con declaraciones preparadas.

Mi registro de consultas MySQL parece:

xxx Connect [email protected] 
xxx Query  set autocommit=0 
xxx Query  INSERT INTO foo_tbl (bar, baz) VALUES ('hello','world') 
xxx Quit 

PHP/DOP no se quejan, pero la selección de la tabla muestra que los datos no se ha escrito.

Las consultas que estoy ejecutando se han ejecutado miles de veces antes; solo se ha realizado el cambio ATTR_AUTOCOMMIT. Al eliminar esa opción, todo vuelve a funcionar. Las transacciones funcionan bien con la opción autocommit=0 también.

¿Hay otras llamadas que es necesario hacer en el objeto PDO (commit() se queja con razón de que no está en una transacción) para hacer que los cambios se queden? Básicamente, quiero un objeto PDO simple pero con la opción de bloquear filas fuera de las transacciones para tablas InnoDB (el fondo de por qué es demasiado largo y aburrido aquí).

Estoy seguro de que esto es algo estúpido que me falta arañazos cabeza

+0

No se preocupe, todos extrañamos cosas a veces! Sé que me pasa mucho más de lo que me gustaría admitir :-) – Josh

Respuesta

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 

Pero, en esencia, que está en una transacción (que simplemente no lo ha iniciado con DOP), una operación de deshacer, etc. . también está disponible. Es bastante discutible si esto es un error (no se puede llamar al commit() directamente).

+0

+1 - Yo diría que es un error ... pero bueno, hay prioridades más altas cuando se habla de PHP API de borked: P Buena respuesta. –

+0

No es un error, es solo un nombre engañoso ya que muchas personas vinculan la palabra "commit" a las transacciones. No significa que sus transacciones sobresalientes se comprometan automáticamente o no, solo significa si sus consultas que no son iniciadas por transacciones se "comprometen" automáticamente o no, que de manera predeterminada, son ... Técnicamente, sus conexiones inician una transacción si está deshabilitada. . –