Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Transaction (nie działają?)
Forum PHP.pl > Forum > PHP
jakal
Jest jakakolwiek możliwość, zby wykonało się 1 zapytanie, a drugie nie? (zakładając, że dane w zmiennych są poprawne)

  1. mysql_query('BEGIN', $linkCron1);
  2. // Dodaj nową platnosc
  3. $query2 = "INSERT INTO transaction_pay (transaction_pay.pay_trans_id, transaction_pay.pay_trans_it_id, transaction_pay.pay_trans_count) VALUES ('".$as_result[$a]->{'deal-transaction-id'}."', '".$as_result[$a]->{'deal-item-id'}."', '".$as_result[$a]->{'deal-quantity'}."')";
  4. if (!mysql_query($query2, $linkCron1)){
  5. mysql_query('ROLLBACK', $linkCron1);
  6. }
  7. else {
  8. // Dodaj informacje o opłaconych towarach
  9. $query2 = "UPDATE transactions SET transactions.pay_quantity=transactions.pay_quantity+".$as_result[$a]->{'deal-quantity'}.", transactions.data_platnosci='".date("Y-m-d H:i:s",$as_result[$a]->{'deal-event-time'})."', transactions.data_przyjeciaplatnosci='".date("Y-m-d H:i:s", $data_teraz)."', transactions.error='0' WHERE transactions.transaction_user_id='".$as_result[$a]->{'deal-buyer-id'}."' AND transactions.allegro_id='".$as_result[$a]->{'deal-item-id'}."' AND transactions.pay_quantity<transactions.buy_quantity";
  10. if (!mysql_query($query2, $linkCron1)){
  11. mysql_query('ROLLBACK', $linkCron1);
  12. }
  13. else {
  14. mysql_query('COMMIT', $linkCron1);
  15. }
  16. }


Ponieważ raz na jakiś czas dodaje mi transakcję (insert into transaction_pay...), ale już nie aktualizuje ilości towarów (update transactions ...)
Wspomnę tylko, że ten kawałek kodu jest dość często uruchamiany (cronem co 3minuty a następnie w pętli po kilkaset razy).

Gdzie szukać problemu?
CuteOne
try/catch + logowanie błędów i wszystko będzie jasne.

ps. po co ci dwa rolback'i?
lukaskolista
Na jakim silniku sa tabele w bazie? Transakcje nie dzialaja na MyISAM.

btw. Twoj kod jest kompletnie bez sensu, po co tworzyc transakcje dla 1 zapytania?
jakal
Cytat
ps. po co ci dwa rolback'i?

Bo jeśli jedno zapytanie się nie uda to -> cofam. Jeśli jedno się uda a drugie nie, też -> cofam (drugim rollback).
Nie tak powinno się to robić?

Cytat
Na jakim silniku sa tabele w bazie? Transakcje nie dzialaja na MyISAM.

Są na InnoDB

Cytat
btw. Twoj kod jest kompletnie bez sensu, po co tworzyc transakcje dla 1 zapytania?

Jakiego jednego? Są dwa: INSERT i UPDATE. Nie powinno zrobić UPDATE, jeśli nie zrobi INSERT i na odwrót.
W takim razie jak to inaczej napisać?
viking
Przejść na PDO i
  1. try {
  2. begin;
  3. zapytania;
  4. } catch (PDOException $e) {
  5. rollback;
  6. }
markonix
Tak się zastanawiam czy po prostu nie możesz sprawdzić czy zapytanie się wykonało i jeśli tak to wykonujesz drugie?

Transakcje wydawało mi się, że służą troszkę bardziej rozbudowanym celom - np. dodawanie tysiąca rekordów - jeden się nie doda to cofasz i naprawiasz.
jakal
Cytat(markonix @ 27.09.2012, 13:02:46 ) *
Tak się zastanawiam czy po prostu nie możesz sprawdzić czy zapytanie się wykonało i jeśli tak to wykonujesz drugie?


Tak robiłem do tej pory, ale czasami zdarzało się, że dodawało do 1 tabeli, ale nie aktualizowało w 2 tabeli.
Dlatego pomyślałem o transakcjach.

Mam jeszcze jeden pomysł.
Bo ten kod jest uruchamiany w cronie i bardzo często używany (setki razy wykonywany co kilka minut).
Na drugiej tabeli jest wykonywanych znacznie więcej operacji, również przez inny cron.

Może po prostu jest natłok operacji na danej bazie i czasami operacje nie są wykonywana?

Jest na to jakaś metoda? Czy blokowanie tablic jest odpowiednie? (nie chciałbym zeby reszta zapytań w tym czasie jak wykonuje jedno to się nie wykonywała lub zwracała błąd, tylko oczekiwała na swoją kolej)


Crozin
@lukaskolista, @markonix: Każda seria zapytań (włączając w to pojedyncze zapytania) musi być objęta transakcją. W przypadku pojedynczych zapytań można sobie co najwyżej darować jawne deklarowanie transakcji, bo domyślnie włączony jest autocommit.

@jakal: Przede wszystkim przydała by się informacja o wystąpieniu błędu. Poza rollbackiem mógłbyś też zapisywać informację o przyczynie niepowodzenia operacji - ułatwiłoby to Ci pracę. Dodatkowo, nie muszę chyba wspominać o tym, że użycie PDO znacznie uprościłoby kod.

Cytat
Na drugiej tabeli jest wykonywanych znacznie więcej operacji, również przez inny cron.
Jakiego typu są to operacje? Mogą one nie mieć kompletnie żadnego znaczenia, być może wystarczy jedynie zwiększyć poziom izolacji transakcji, a być może rzeczywiście trzeba będzie blokować całą tabelę.

EDIT: Sam kod, mimo iż tragicznej jakości, wydaje się być w porządku. Problem jest prawdopodobnie gdzie indziej.
jakal
Cytat
@jakal: Przede wszystkim przydała by się informacja o wystąpieniu błędu. Poza rollbackiem mógłbyś też zapisywać informację o przyczynie niepowodzenia operacji - ułatwiłoby to Ci pracę. Dodatkowo, nie muszę chyba wspominać o tym, że użycie PDO znacznie uprościłoby kod.

Tak chyba zrobię, jeśli drugie zapytanie się nie wykona to zapiszę czemu, razem z treścią zapytania.
Wiem, że PDO by ułatwiło, ale aplikacja ma za dużo kodu, żeby teraz zmieniać wszytko na PDO.


Cytat
Jakiego typu są to operacje?

W większości SELECT, ale też często UPDATE.

Cytat
EDIT: Sam kod, mimo iż tragicznej jakości

Czemu tragiczna jakość? wink.gif Po prostu czysty PHP + MYSQL, nie obiektowy.
Crozin
Cytat
Tak chyba zrobię, jeśli drugie zapytanie się nie wykona to zapiszę czemu, razem z treścią zapytania.
Wiem, że PDO by ułatwiło, ale aplikacja ma za dużo kodu, żeby teraz zmieniać wszytko na PDO.
Powinieneś zapisywać informację o wystąpieniu dowolnego, nawet nieistotnego błędu i najlepiej od razu przerywać działanie całej aplikacji w przypadku jego wystąpienia. Kod, który generuje nieobsłużone błędy właściwie z definicji działa w sposób nieokreślony.
Cytat
W większości SELECT, ale też często UPDATE.
Nie da się teraz stwierdzić czy te zapytania mają w ogóle jakikolwiek związek z problemem, ale być może zapytania SELECT operują na innym niż przewidywanym zestawie rekordów - skutek modyfikowania tabeli przez inny proces. Poczytaj o wspomnianych wcześniej poziomach izolacji transakcji, to będziesz wstanie stwierdzić czy to może powodować błąd.
Cytat
Czemu tragiczna jakość? Po prostu czysty PHP + MYSQL, nie obiektowy.
Brak obsługi błędów, nie korzystanie z preparowanych zapytań w momencie gdy to samo zapytanie jest wykonywane setki razy z rzędu, brak odpowiedniego przygotowania danych do wrzucenia w treść zapytania SQL, niepotrzebnie wiele poziomów zagłębienia kodu, niepotrzebne powtarzanie fragmentów kodu, nieczytelne nazwy zmiennych/formatowanie kodu... to tak na pierwszy rzut oka.
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.