2010-11-01 11 views
7

Been zarysowania głowę na ten temat na chwilę ....PDO :: ATTR_AUTOCOMMIT ignoruje nietransakcyjnych Wstaw/aktualizacja

Mam obiekt PDO z pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0); jak chcę użyć FOR UPDATE z niektórych tabelach InnoDB. Czytanie dokumentacji MySQL, FOR UPDATE zablokuje tylko czytać wiersze, jeżeli:

  1. Jesteś w transakcji
  2. Jesteś nie w transakcji i set autocommit=0 wydano

więc jestem przy użyciu ATTR_AUTOCOMMIT, aby umożliwić obiektowi PDO blokowanie wierszy. W obu przypadkach powoduje to, że instrukcje INSERT i UPDATE nie mają zastosowania. Te stwierdzenia nie mają nic wspólnego z FOR UPDATE po prostu przebiegają przez ten sam obiekt PDO z przygotowanymi instrukcjami.

My MySQL kwerendy dziennika wygląda następująco:

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

PHP/PDO nie narzeka, ale wybierając z tabeli wynika, że ​​dane nie zostały zapisane.

Kwerendy, które używam, zostały uruchomione tysiące razy wcześniej; wprowadzono tylko zmianę ATTR_AUTOCOMMIT. Usunięcie tej opcji powoduje, że wszystko działa ponownie. Transakcje działają poprawnie również z opcją autocommit=0.

Czy są jakieś dodatkowe wywołania, które muszą być wykonane na obiekcie PDO (commit(), jak słusznie nie jest w transakcji), aby zmiany zostały wprowadzone? Zasadniczo chcę zwykły obiekt PDO, ale z opcją blokowania wierszy poza transakcjami dla tabel InnoDB (tło dla tego, dlaczego jest tu zbyt długie i nudne).

Jestem pewien, że to jest coś, głupi jestem brakujące zadrapania głowy

+0

Nie martw się, czasami tęsknimy za różnymi rzeczami! Wiem, że zdarza mi się to znacznie więcej, niż chciałbym przyznać :-) – Josh

Odpowiedz

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 

Ale zasadniczo, jesteś w transakcji (po prostu nie zaczęli go z PDO), cofnięcia etc . jest nadal dostępny. Jest dość dyskusyjne, czy jest to błąd (nie można bezpośrednio zadzwonić pod numer commit()).

+0

+1 - Powiedziałbym, że to błąd ... ale hej, są wyższe priorytety, gdy mówimy o zepsutym API PHP: P Dobra odpowiedź. –

+0

To nie jest błąd, to tylko mylące nazwisko, ponieważ wiele osób łączy słowo "commit" z transakcjami. Nie oznacza to, że twoje zaległe transakcje są automatycznie zatwierdzane lub nie, to po prostu oznacza, czy zapytania, które nie zostały rozpoczęte przez transakcje, są automatycznie "zatwierdzane", czy też nie, które domyślnie są ... Technicznie twoje połączenia rozpoczynają transakcję, jeśli jest wyłączona . –