2014-05-25 16 views
6

Dokumentacja PHP PDO::commit() stwierdza, że ​​metoda zwraca TRUE w przypadku sukcesu lub FALSE w przypadku niepowodzenia. Czy odnosi się to do sukcesu lub niepowodzenia instrukcji oświadczenia między beginTransaction() i commit()?PDO :: commit() sukces lub niepowodzenie

Na przykład z dokumentacji:

$dbh->beginTransaction(); 
$sql = 'INSERT INTO fruit (name, colour, calories) VALUES (?, ?, ?)'; 
$sth = $dbh->prepare($sql); 

foreach ($fruits as $fruit) { 
    $sth->execute([ 
     $fruit->name, 
     $fruit->colour, 
     $fruit->calories, 
    ]); 
} 

$dbh->commit(); 

Jeżeli którykolwiek z powyższych egzekucji zawiodą,() metoda będzie popełnić return false ze względu na „zasadzie wszystko albo nic” transakcji atomowych?

+0

Naprawdę nie przypominam sobie, żebyś musiał dokonać zatwierdzenia w bazie kodu, czy próbowałeś to zrobić bez niego? – Jonast92

+0

Nie jestem pewien, czy rozumiem.Celem ręcznych transakcji jest upewnienie się, że wiele instrukcji zakończyło się sukcesem, lub żadne z nich nie powiodło się. –

+0

Myślę, że nad tym się zastanawiasz. Jeśli się nie uda w tym scenariuszu, najprawdopodobniej wszystko zawiedzie i na odwrót. Po prostu dodaj poprawną obsługę błędów do kodu i jeśli naprawdę martwisz się, co się nie udaje, po prostu zaloguj się. Nigdy nie musiałem używać commit w kodzie po stronie serwera, więc wydaje mi się, że jest to mało prawdopodobne. – Jonast92

Odpowiedz

2

Wartość zwracana jest oparta na samym sile pdo :: commit, a nie na transakcji, którą próbujesz zatwierdzić. Zwraca FALSE, gdy nie ma żadnej transakcji aktywnej, ale nie jest bardzo jasne, kiedy powinna zwracać wartość TRUE lub FALSE.

Wykonane zapytania w ramach samej transakcji zakończą się sukcesem lub niepowodzeniem. Posługując się przykładem Mr.Tk, transakcja zostanie zatwierdzona, jeśli to możliwe, i nie wystąpił błąd podczas wykonywania zapytań w bloku "try" i wycofany, jeśli wystąpił błąd w bloku "try".

Analizując tylko wykonane kwerendy w bloku "spróbuj", osobiście spróbowałabym wychwycić wyjątek PDOException zamiast normalnego wyjątku.

$dbh->beginTransaction(); 
try { 
    // insert/update query 
    $dbh->commit(); 
} catch (PDOException $e) { 
    $dbh->rollBack(); 
} 
0

Zawsze odbywa się to w ten sposób:

$dbh->beginTransaction(); 

try { 
    // insert/update query 

    $dbh->commit(); 
} catch (Exception $e) { 
    $dbh->rollBack(); 
} 

I zawsze działało jak uroku! :)

Więc myślę, że w twoim przypadku, gdyby wstawienie się nie powiodło, aplikacja powinna rzucić wyjątek, a zatwierdzenie nawet nie wyzwoli.

3

Kluczowym elementem jest ustawić PDO w trybie wyjątku, mając try-catch tylko zrobić rollback jest niepotrzebna. Zatem, kod jest w porządku, nie ma potrzeby, aby go zmienić jeśli chcesz to wycofywania w przypadku niepowodzenia, jak długo masz tę linię gdzieś:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

W przypadku awarii skrypt zostanie zakończone, połączenie zamknięte i mysql z przyjemnością wycofa transakcję za Ciebie.

Jeśli nadal chcesz ręcznie wycofywać, powinieneś robić to poprawnie, nie tak jak w innych odpowiedziach. Upewnij się, że

  • jesteś połowu Exception, nie PDOException, gdyż nie ma znaczenia, co szczególnie wyjątek przerwana wykonanie
  • jesteś ponownego rzucania wyjątek po wycofania, aby otrzymywać powiadomienia o problemie
  • również, że silnik tabeli obsługuje transakcje (np. Dla MySQL powinien to być InnoDB, a nie MyISAM).

Ta lista kontrolna została zaczerpnięta z my article, która może okazać się przydatna również w tym lub wielu innych aspektach.

+0

Czy jesteś tego pewien? Jeśli wykonuję 10 różnych wstawień lub aktualizacji, a w ostatnim pdo podnosi wyjątek, wszystkie pozostałe 9 zdań są wycofane? –

+0

Zgadzam się z @CarlosGoce: nie wycofa się bez jawnej obsługi "rozpocznij/wycofaj". Ale wyjątki pomogą w uruchomieniu "przywracania", jak stwierdził @ Mr.TK. W rzeczywistości nie odpowiadasz nawet na pytanie o 'commit': transakcje są przydatne, jeśli chcesz anulować wiele wcześniej wysłanych zapytań, jeśli coś pójdzie nie tak. – Yvan

+0

@Yvan na pewno zostanie wycofany, ponieważ transakcja zawsze zostanie wycofana z * połączenia *. Ale wolałbym się zgodzić z tym, że przy transakcjach spróbować catch jest użyteczny, jeśli jest właściwie wykorzystywany. –