To jest trudne do wytłumaczenia (i bardzo dziwne), więc proszę o mnie. Wyjaśnię problem i naprawię go, ale chciałbym zobaczyć, czy ktoś może wyjaśnić, dlaczego działa tak, jak działa :)Obsługa bazy danych DBI z AutoCommit ustawiona na 0, która nie zwraca właściwych danych za pomocą SELECT?
Mam aplikację internetową, która używa mod_perl. Korzysta z bazy danych MySQL i regularnie zapisuję dane w bazie danych. Jest modułowy, więc ma również swój własny typ "bazy danych" modułu, w którym obsługuję połączenia, aktualizacje itp. Baza danych :: db_connect() jest używana do łączenia się z bazą danych, a AutoCommit
jest ustawiona na 0.
Zrobiłem kolejną aplikację Perla (samodzielny demon), która okresowo pobiera dane z bazy danych i wykonuje różne zadania w zależności od zwracanych danych. Załączam do niego moduł database.pm, więc nie muszę przepisywać/duplikować wszystkiego.
Problem mam przeżywa to:
Aplikacja połączy się z bazą danych przy starcie, a następnie pętli zawsze, pobierania danych z bazy danych co X sekund. Jeśli jednak dane w bazie danych zostaną zaktualizowane, moja aplikacja nadal będzie zwracana "stare" dane, które dostałem na początkowe połączenie/zapytanie do bazy danych.
Na przykład - Mam 3 wiersze, a kolumna "Nazwa" ma wartości "a", "b" i "c" - dla każdego rekordu. Jeśli zaktualizuję jeden z wierszy (na przykład przy użyciu klienta mysql z wiersza poleceń) i zmienię nazwę z "c" na "x", mój autonomiczny demon nie otrzyma tych danych - nadal będzie otrzymywał/b/c zwrócony z MySQL. Przechwyciłem ruch db za pomocą tcpdump i mogłem zdecydowanie zobaczyć, że MySQL naprawdę zwrócił te dane. Próbowałem używać SQL_NO_CACHE również z SELECT (ponieważ nie byłem pewien, co się dzieje), ale to też nie pomogło.
Następnie zmodyfikowałem ciąg połączenia DB w moim autonomicznym demonie i ustawiłem AutoCommit
na 1. Nagle aplikacja zaczęła uzyskiwać poprawne dane.
Jestem zdziwiony, ponieważ sądziłem, że AutoCommit wpływa tylko na instrukcje typu INSERT/UPDATE i nie ma wpływu na instrukcję SELECT. Ale na pozór tak jest i nie rozumiem dlaczego.
Czy ktoś wie, dlaczego instrukcja SELECT nie zwróci "zaktualizowanych" wierszy z bazy danych, gdy AutoCommit
jest ustawiona na 0, i dlaczego zwróci zaktualizowane wiersze, gdy AutoCommit
jest ustawiona na 1?
Oto uproszczony (usunięty sprawdzanie błędów itp.) Kod, którego używam w autonomicznym demonie, który nie zwraca zaktualizowanych wierszy.
Zmiana AutoCommit
na 1 to rozwiązuje. Czemu?
Thanks :)
P.S: Nie wiem, czy ktoś to obchodzi, ale wersja DBI jest 1,613, DBD :: mysql jest 4,017, Perl 5.10.1 (Ubuntu 10.04).
Czy ustawienie 'auto_commit' jest włączone lub wyłączone w kliencie mysql z wiersza poleceń (gdzie wykonano operację' UPDATE')? – Ether
Jest włączony (domyślnie włączony i nie zmieniłem go). Widzę "nowe" zaktualizowane dane od klienta mysql lub jakiejkolwiek innej "sesji" (nowa sesja DBI, która łączy się lub dowolny inny klient, który łączy się z bazą danych) - to tylko sesja z AutoCommit 0, która nie może uzyskać dostępu do zaktualizowanych danych . – sentinel