Temat: Mysql - translacje

Pierwsze primo. Nie translacje tylko transakcje
Drugie primo. Jak używasz transakcji to już nie lockuj tabel.
Trzecie primo. Może po prostu masz skopane zapytania?
Marek Janiak

Marek Janiak JEstem pro

Temat: Mysql - translacje

Ad.1 przepraszam za pomyłkę.. to zmęczenie po szkole
Ad.2 Nie lokuje tabel tylko elementy i z tego co mi wiadomo tego inaczej nie da się zrobić, a mianowicie: Pobieram czy użytkownik ma wiecej niż 1 kredyt na swoim koncie. Nastepnie wykonuje zmiany w jakis tabelach innych. I nastepnie odejmuje mu 1 kredyt. Bez zablokowania danego elementu moga wystąpić duże problemy np. minusowa ilosc kredytów.
Ad.3 na 100% nie ponieważ all zapytania zapisuje i nie są one błędne. Tak jakby mysql dostał freeza na wszystko co dotyczy danej tabeli
Marcin K.

Marcin K. Programowanie jest
moim powołaniem,
Alleluja

Temat: Mysql - translacje

W bazie MySQL w plikach konfiguracyjnych włączyć nalezy autocommit lub podczas połączenia z bazą danych wywołać komendę. Nawet jeśli zapomniałeś zakończyć operację COMMIT to po wykonaniu polecenia automatycznie odblokuje dany rekord.

W MySQL mamy do wyboru 2 mechanizmy wstrzymania operacji na tabeli/rekordzie

- blokowanie całej tabeli
- blokowanie tylko tego rekordu

ten artykuł może pomóc:
http://www.databasejournal.com/features/mysql/article....

Temat: Mysql - translacje

Bartłomiej Graczyk:
Ad.2 Nie lokuje tabel tylko elementy i z tego co mi wiadomo tego inaczej nie da się zrobić, a mianowicie: Pobieram czy użytkownik ma wiecej niż 1 kredyt na swoim koncie. Nastepnie wykonuje zmiany w jakis tabelach innych. I nastepnie odejmuje mu 1 kredyt. Bez zablokowania danego elementu moga wystąpić duże problemy np. minusowa ilosc kredytów.

Ale ty mnie nie rozumiesz. Transakcje same z siebie blokują tabele
więc nie musisz ich blokować drugi raz.
Ad.3 na 100% nie ponieważ all zapytania zapisuje i nie są one błędne. Tak jakby mysql dostał freeza na wszystko co dotyczy danej tabeli

Nie chodziło mi o błędy składniowe tylko ideologiczne powodujące dużą złożoność obliczeniową.

konto usunięte

Temat: Mysql - translacje

Zapodaj kod procedury SQL to będzie łatwiej znaleźć błąd
Marek Janiak

Marek Janiak JEstem pro

Temat: Mysql - translacje

Po długich analizach zachowań systemu doszedłem do wniosku, że problem pojawia się w transakcjach. Przedstawie prosty przykład:

Jeśli użytkownik posiada punkty to ma mu jeden odjąć i coś wykonać.

1.) mysql_query("START TRANSACTION;");
2.) $query = wykonaj_sql("SELECT `ilosc_punktow` from `uzytkownicy` WHERE login = '".$login."' LIMIT 1 LOCK IN SHARE MODE");
3.) $punkty = mysql_result($query,0,0);
4.) if ($punkty == 0) { wykonaj_sql("UPDATE `uzytkownicy` SET `ilosc_punktow` = `ilosc_punktow` - 1 WHERE login = '".$login."'"); ...Jakieś zapytanie.... }
5.) mysql_query("COMMIT;");

W niektórych momentach dochodzi do sytuacji, w której dane elementy blokują sie, a mianowicie gdy chce wykonać zapytanie dotyczace tabeli `uzytkownicy`:
SELECT * from `uzytkownicy` WHERE `login` = '$login'

Otrzmuje blad: #1205 - Lock wait timeout exceeded; try restarting transaction

Moje wnioski:
Po wykonaniu LOCK IN SHARE nastepuje np. zerwanie polaczenia przez co skrypt w danym polaczeniu nie moze wykonać "COMMIT;" odblokowywujac w ten sposób blokade na element.

Jakieś propozycje?

Z góry dziękuję i pozdrawiamBartłomiej Graczyk edytował(a) ten post dnia 21.11.08 o godzinie 21:16

Temat: Mysql - translacje

Ja pierniczę. Ile razy trzeba Ci pisać, że albo używasz locków albo transakcji?

konto usunięte

Temat: Mysql - translacje

A dlaczego nie zrobisz tylko UPDATE z dodatkowym warunkiem
WHERE ilosc_punktow > 0

O ile się nie mylę to Mysql od wersji 5.0 obsługuje procedury wbudowane i lepiej z nich korzystać.Bogdan Pieńkowski edytował(a) ten post dnia 22.11.08 o godzinie 17:40
Marek Janiak

Marek Janiak JEstem pro

Temat: Mysql - translacje

Po długich analizach doszedłem do wniosku że problem nie leży w transakcjach. Co jakiś czas można odczuć tak zwany freez, w którym przez mysql CPU skacze do 100% nastepnie zapytania dodaje do slow-query i wszystko wraca do normy. Wydaje mi sie że problem prawdopodobnie leży po stronie cache w pamięci. Nie wiem czy to działa tak że mysql trzyma all w pamięci i w pewnym momencie zrzuca wszystko na dysk, ponieważ busy dysku = 100%. Nie wiem jak naprawić występujący problem.
Oto zrzut ekrany w wyniku freeza:

Obrazek


dodam, iż w momencie freeza nie mam dostępu do bazy. Ale tuż przed lagiem nie wykonywane są żadne skomplikowane zapytania.
my.cnf http://phpfi.com/383720
phpmyadmin status:
Obrazek

konto usunięte

Temat: Mysql - translacje

Prędzej zrobiłeś sobie sam krzywde złym zapytaniem, bez jakiegoś połączenia i robisz np. update XXX.XXX wierszy, co w połaczeniu z transakcją przepełnia bufor? ;] Posprawdzaj czy masz wszystkie indeksy, dobre złączenia etc. I co najważniejsze wyciągaj wnioski z tego co ci tu ludzie radzą. Osobiście proponuję kupic sobie książke o mySQL lub chociaż sciągnac dobrego PDF'a z przykładami, bo kod na chwilę obecną masz "przeuroczy".

Gn8.
Rafał.
Marek Janiak

Marek Janiak JEstem pro

Temat: Mysql - translacje

Ja ogólnie przedstawiłem jakiego typu zapytania wykonuje. Problem w tym że dzieje się tak nawet gdy nie używam transakcji.
Piotr Sikora

Piotr Sikora Specjalista Web i
Video

Temat: Mysql - translacje

Jak dla mnie wogole dziko wyglada to zapytanie.
Nie lepiej zrobic UPDATE potem SELECT-em sprawdzic czy dane sa poprawne.
jesli tak to COMMIT , a jesli nie to ROLLBACK ?
BTW fakt tego LOCK-a wywal ;)
Marcin K.

Marcin K. Programowanie jest
moim powołaniem,
Alleluja

Temat: Mysql - translacje

jeśli zrobisz SELECT po UPDATE, ale przed COMMIT to masz cały czas dane z
przed tej operacji (dla innych otwartych sesji które mogą wykonywać podobną operację na rekordzie), ale już nowe dane dla tego połączenia i nie możesz sprawdzić co dzieje się w tle. Piotrze nie tędy droga, tu jest serwis aukcyjny. Nie ma czasu na UPDATE potem SELECT i sprawdzanie czy jest ok. W jednej chwili może być nawet setka takich operacji na rekordzie np allegro i może dochodzić do rozbieżności.

Strona z aukcjami to nie wordpress czy os-commerce tutaj naprawdę ważne są transakcje.

Poczytać radzę o segmencie wycofania dla zrozumienia bajeczki poniżej.

To czy dane są poprawne sprawdza się przed wpisaniem do bazy lub mechanizmami zaimplementowanymi w samym silniku bazy jak chociażby check (postgres), enum(mysql). Oczywiście to najprostrzy sposób. Zostają jeszcze procedury,funkcje itd...

Można jeszcze użyć pytań zagnieżdzonych. UPDATE z SELECT, jeśli to pomoże

sprawdźmy jak by to wyszło przez UPDATE i potem SELECT (pomysł Piotra).
sprawdzam stan konta w bankomacie mam 300zl pobieram 100zl UPDATE (-100), babcia wyplaca sobie z mojego konta w tym samym czasie np 1ms później np. przez internet sprawdza mam stan 300zl bo ja jeszcze w operacji nie zrobilem COMMIT. Babcia pobiera z mojego konta 300zl UPDATE(-300) i sprawdza SELECT, ale przed moim COMMIT i wychodzi ok mimo że już ja pobrałem 100zł (no ale przecież nie zatwierdziłem tak?, to znaczy że nie wprowadziłem zmian do tabeli). teraz ja robie COMMIT i babcia robi COMMIT i jest tak stan konta 300-100-300 = - 100zł. Hm... i co teraz mam przecież DEBET, a miec nie powinienem. ;)

Fajna bajeczka co? Może dlatego że już po północy. Chciałem tylko przedstawić błąd jaki może choć nie musi wyniknąć przez to
polecenie.Marcin Kossak edytował(a) ten post dnia 03.12.08 o godzinie 00:39

konto usunięte

Temat: Mysql - translacje

1. Wrzuc to do procedury, bedzie szybciej i bezpieczniej.

2. UPDATE `uzytkownicy` SET `ilosc_punktow` = `ilosc_punktow` - 1 WHERE login = '".$login."' AND `ilosc_punktow` > 0

3. SELECT LOCK IN SHARE MODE and FOR UPDATE

4. The InnoDB Transaction Model and Locking

5. Cos o poziomach izolacji transakcji
Piotr Sikora

Piotr Sikora Specjalista Web i
Video

Temat: Mysql - translacje

Marcin: Nie jest tak jak mowisz, chyba ze zle to wytlumaczylem.
W momencie kiedy ja zrobie w tranzakcji UPDATE -100 , a potem Babcia wejdzie i bedzie chciala zrobic UPDATE -300 , ale ja jeszcze COMMITA nie zrobilem
to UPDATE Babcia bedzie czekal na mojego COMMITA poniewaz bedzie lock.
Jak ja zrobie COMMIT na -100 zl z bankomatu , potem BABCIA zrobic UPDATE
to Babcia po tranzakcji zobaczy ze stan jest -100 i wtedy robi sie Rollback.
Moze wyjasnie to SQLem ;) :
mysql_query("START TRANSACTION;");
mysql_query("UPDATE tblTranzaction SET lngBalance = lngBalance - 100 WHERE lngUID=1;");
$q = mysql_get_val("SELECT lngBalance FROM tblTranzaction WHERE lngUID = 1;")
if($q>=0)
mysql_query("COMMIT;");
else
mysql_query("ROLLBACK");
Marcin K.

Marcin K. Programowanie jest
moim powołaniem,
Alleluja

Temat: Mysql - translacje

Opisałem to zdarzenie na zasadzie babki ;), bo już spotkałem się z tym problemem i robiłem to także na Twój sposób, niestety nie pomógł tak jak chciałem, dopiero stworzenie procedury rozwiązało wszystko. W moim wypadku nie mogłem ryzykować i modlić się czy będzie działało tym razem, a może następnym. Dzięki temu jeszcze nie siedzę w kredytach płacąc za błędy ;).

Ja polecam oczywiście jak najtrudniejsze rozwiązania i przede wszystkim niezawodne, bo dzięki temu zarabiam dużo, jestem niezastąpiony no i co najważniejsze nie stoję w tym samym szeregu co osoba, która kupiła ksiązkę za 5zł pod nazwą "PODSTAWY SQL". Mam tą świadomość i zadowolenie, że wszystko działa jak należy.
Rozwiązanie zależy oczywiście od złożoności problemu i jego wagi.

Bym zapomniał poczytaj Piotrze o transakcjach w MYSQL(manual dla wersji 5.x) a dokładniej o DML, współbierzności oraz wykorzystanie SELECT FOR UPDATE

Podobny problem był opisany w konkursie "Grasz o staż"Marcin Kossak edytował(a) ten post dnia 07.12.08 o godzinie 04:29
Piotr Sikora

Piotr Sikora Specjalista Web i
Video

Temat: Mysql - translacje

Może nie działało jak chciałeś bo miałeś autocommit włączony ?
Dokumentacje dobrze znam i tez nie siedze na kredytach ;)

Następna dyskusja:

Zapytanie MySQL




Wyślij zaproszenie do