Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rolback w zapytaniu SQL ?
Forum PHP.pl > Forum > PHP
ahold
witajcie,


Męczę formularz rejestracyjny.
W jakis posób wydać komendę rolback korzystając z takiego przykładu


$wynik=$dbh->exec("INSERT INTO xxxx (xxxx, xx,xxxx) VALUES ('xxx','$xxx','$id_xxx')");

wysyłanie maila
{
//ok
}
else
//awaria
{
rolback kod u góry
print('Fail');
}
Robert007
jeżeli wstawiasz zmienne w zapytaniu to musisz robić w cudzysłowiach czyli tak:

  1. <?php
  2. "$id_xxx" #powinno być pogrubiony kolor
  3. ?>


lub takie sposoby:

  1. <?php
  2. '.$id_xxx.'
  3. ?>


lub

  1. <?php
  2. " . $id_xxx. "
  3. ?>
ahold
Kod
<?php

$dbh->beginTransaction();
$wynik=$dbh->exec("INSERT INTO xxxx (xxxx, xx,xxxx) VALUES ("xxx","$xxx","$id_xxx")");

wysyłanie maila
{
//ok
$dbh->commit();
}
else
//awaria
{
$dbh->rollBack();
print('Fail');
}
?>

Czy tak posługuje się komendą roolBack ?
erix
A nie mogłeś sprawdzić? tongue.gif
ahold
Pytam, czy dobrze kombinuje.

Mój pierwszy pomysł, polegał na DELETE from xxx jeżeli wysłanie maila się "nie powiedzie", ale przypomniała mi się funkcja roolback.

Tylko nie wiem, czy pozwala ona na wykorzystanie w wypadku innego wyjątku, takiego "mojego". Wiem że pisana była pod kontem wielo zapytań do serwera SQL typu odejmij xxx z konta y, dodaj xxx na konto x. Jeżeli się nie powiedzie, roolback.

Nigdy nie miałem doczynienia z tym, w wypadku innej funkcji.
Zaraz się, przekonamy kolego !
fander
Aby użyć rollback najpierw musisz rozpocząć transakcje. Jeśli zrobisz coś takiego
$dbh->exec("INSERT INTO xxxx (xxxx, xx,xxxx) VALUES ("xxx","$xxx","$id_xxx")"); gdzie w exec nie ma transakcji to doda ci do bazy to co chciałeś.
Transaction, Rollback, Commit działa na bazie danych a nie w php chyba że ktos napisał własna metodę która działa na poziomie php

http://dev.mysql.com/doc/refman/5.0/en/commit.html

Napisz z jakiego konektora kozystasz do łączenia z bazą (PDO etc).
viking
Powiedzcie mi czemu ludzie nie raczą nigdy zajrzeć do dokumentacji?
http://pl2.php.net/manual/en/pdo.transactions.php

@fender: kod jaki podaje ahold jest tylko w PDO (no i w nowym sqlite dla php 5.3 z którego pewnie nie korzysta).
fander
masz racje
ahold
Niestety, nie mogę dojść do tego.
Korzystam z PDO.

Czy faktycznie nie ma tam funkcji, do cofnięcia zmian w MySQL w sytuacji kiedy PHP napotka na błąd ?

Tzn, ja napotkam błąd w kodzie, i chcę wycofać zmiany.
omeck
Cytat(viking @ 2.07.2009, 13:18:47 ) *
Powiedzcie mi czemu ludzie nie raczą nigdy zajrzeć do dokumentacji?
http://pl2.php.net/manual/en/pdo.transactions.php


Autorowi nie do końca o to chodzi.

Cytat(viking @ 2.07.2009, 13:18:47 ) *
Czy faktycznie nie ma tam funkcji, do cofnięcia zmian w MySQL w sytuacji kiedy PHP napotka na błąd ?

W sumie dobre pytanie. Rollback jest wykonywany na wskutek przechwycenia wyjątku, który wyrzuca adapter, wskutek błędu, który wyrzuca baza... Nigdy w sumie nie miałem takiego problemu, aby cofać zmiany jeśli kod php jest nieprawidłowy - nie można go przebudować?
ahold
Cytat(omeck @ 7.07.2009, 15:27:04 ) *
Autorowi nie do końca o to chodzi.
W sumie dobre pytanie. Rollback jest wykonywany na wskutek przechwycenia wyjątku, który wyrzuca adapter, wskutek błędu, który wyrzuca baza... Nigdy w sumie nie miałem takiego problemu, aby cofać zmiany jeśli kod php jest nieprawidłowy - nie można go przebudować?



Dokładnie. Mi nie chodzi o doskonale opisaną metodę roolback w sytuacji kiedy jedna zapytanie na dwa, się nie powiedzie. Wtedy tam właśnie mamy przechwytywanie wyjątku, i roolback.

Mi chodzi o prostą sytuację.
Przykład

1) generuje użytkownikowi nowe hasło
2) dodaje do bazy danych
3) Wysyłam e-mail - zmieniłem Ci hasło

Nastąpiła awaria bo wewnętrzny serwer smtp poleciał. Tak więc e-mail nie został wysłany. Łapie mi to wyjątek w php, odpowiedni w bibliotece stwierdzający awarie serwera
if awaria {
Wiadomość nie może być wysłana, serwer smtp leży.
}

I teraz trzeba cofnąć te zmianę w serwerze mysql, ponieważ, zmieniliśmy hasło, ale nie dotrze ono do użytkownika.


Potrzebuję takie wywołanie
if awaria
{
cofnij ostatnie zapytania, które były np po "begin trans action "
}


Naprawdę długo szukałem tego na Google, i wszędzie przykłady dotyczyły przechwytywania, błędów w zapytaniach.
Czemu więc po prostu wywołanie roolback() nie odnosi sukcesu.


Jeżeli ma prawo reagować na błąd w mysql to czemu nie może też php wywołać procedury cofania.
omeck
Cytat(ahold @ 7.07.2009, 16:18:20 ) *
1) generuje użytkownikowi nowe hasło
2) dodaje do bazy danych
3) Wysyłam e-mail - zmieniłem Ci hasło


Czy możliwa jest zamiana punktu 2 z 3? najpierw wysyłać maila, a potem jeśli się udało wykonać operacje na bazie?

Cytat(ahold @ 7.07.2009, 16:18:20 ) *
Naprawdę długo szukałem tego na Google, i wszędzie przykłady dotyczyły przechwytywania, błędów w zapytaniach.
Czemu więc po prostu wywołanie roolback() nie odnosi sukcesu.
Jeżeli ma prawo reagować na błąd w mysql to czemu nie może też php wywołać procedury cofania.


Może taki mały hack - skoro wyłapałeś błąd w php, to wykonaj celowo jakieś złe zapytanie SQL - transakcja powinna to przechwycić i rollback powinien zadziałać. Przynajmniej tak mi się wydaje tongue.gif
ahold
Kajam się i proszę o wybaczenie.
Dokładnie 6 godzin zajęło mi odnalezienie rozwiązania.

Mianowicie jakiś ekspert położył tabelę w my_isami :/

Po zmianie na inno_db oczywiście ruszyło.


Cytat(omeck @ 7.07.2009, 16:48:44 ) *
Czy możliwa jest zamiana punktu 2 z 3? najpierw wysyłać maila, a potem jeśli się udało wykonać operacje na bazie?
Może taki mały hack - skoro wylapaleś błąd w php, to wykonaj celowo jakieś zle zapytanie SQL - transakcja powinna to przechwycić i rollback powinien zadziałać


Myślałem, powiedz czy dobrym rozwiązaniem jest dostać e-mail, z hasłem które nie działa ^^



Ale rozwiązaliśmy problem:

Bo ruszyło, a ten kod który mam u góry jest poprawny.
Nie działało, bo facet położył tabelę w my_isami.
Wiesz, nie wpadło by mi do głowy żeby to sprawdzić.

Teraz ruszyło.


Działający example:

  1. <?php
  2. //Dodaje do serwera
  3. $dbh->beginTransaction();
  4. //$wynik=
  5. $dbh->exec("INSERT INTO root_passwords_node1 (ip,password,security_code,username) VALUES ('$ip','$passwordhashed','$key','$userlogin')");
  6.  
  7. //Dodaje do serwera
  8. ?>


Tutaj mamy kod który generuje błąd.

  1. <?php
  2. if(!$mail->Send()) {
  3.    //Mail NIE wysłany
  4. //COFAM MYSQL
  5. $dbh->rollBack();
  6. //COFAM MYSQL
  7. echo "Awaria w wysyłce poczty, prawdopodobnie klaster jest offline. Spróbuj za 5 minut.";
  8.  
  9. //echo $mail->ErrorInfo."<br>";
  10.  
  11. exit();
  12. }else
  13. {
  14. //Mail wysłany !
  15. $dbh->commit();
  16. //Mail wysłany !
  17. }
  18. ?>
fander
Przecież właśnie zamieniłeś punkt 2 z 3 wykonałeś commit po tym jak sprawdziłeś czy poszedł mail !
mogłeś zrobić tak:
Kod
if($mail->Send()){
   $dbh->exec($zapytanie);
}
else{
   echo "Awaria !";
}


myślenie nie boli
ahold
Wykonałem commit zapytania które się udało wykonać. Na tym przykładnie źle to widać, no ale cóż.


To zły przykład na 1 pliku, ale w inftastrukturze xxxx users, od razu zmiana musi zostać zapisana, inaczej ktoś ją nam po prostu nadpisze. I zaczną się jaja.

Trzeba brać pod uwagę nie tylko awarię serwera smtp, ale równiez mysql który jest osobną maszyną.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.