Po przekroczeniu limitu wait_timeout mysql tracę połączenie ze skryptem PHP CLI. Nie mogę zmienić wait_timeout, więc jak zbudować instrukcję try/catch, która ponownie łączy się, gdy używam PDOStatement do wykonywania moich zapytań?PDO z PDOStatement reconnect po błędzie "mysql server gone"
Odpowiedz
Najlepszym sposobem jest zawinięcie tworzenia instancji PDO do postaci singleton (np. MyPDOFactory), która przechowuje zarówno instancję, jak i czas utworzenia, w ten sposób można go ponownie użyć lub odtworzyć po osiągnięciu TTL (2 lub 3 sekundy to więcej niż wystarczająca ilość dla większości aplikacji). Musisz tylko wywołać MyPDOFactory :: get(), aby uzyskać poprawny PDO, którego możesz użyć do przygotowania PDOStatement, po prostu upewnij się, że wykonujesz go JAK NAJSZYBCIEJ.
Myślę, że to może ci pomóc.
/* Your Database Name */
$dbname = 'mydatabase';
/* Your Database User Name and Passowrd */
$username = 'root';
$password = 'password';
try {
/* Establish the database connection */
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/* your code goes here*/
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
//mysql_close($conn);
$conn=null;
Twoja odpowiedź jest bezużyteczna w przypadku ponownego łączenia po upływie limitu czasu. W bloku try powinieneś umieścić kod zapytania i jeśli połączenie zniknęło, podłącz ponownie blok catch. A potem jakoś uruchom ponownie zapytanie ... –
Ponowne połączenie z bazą danych po błędzie jest w rzeczywistości znacznie bardziej skomplikowanym problemem niż na pierwszy rzut oka.
Moim pierwszym pomysłem było napisać prosty klasy otoki dla PDO, że serwery proxy metod na wewnętrznej obiektu PDO i może obsługiwać błędy połączenia sama:
class BetterPDO extends PDO
{
private $realPDO = NULL;
private $dsn = "";
private $username = "";
private $password = "";
private $options = [];
public function __construct ($dsn, $username = "", $password = "", $options = [])
{
$this -> dsn = $dsn;
$this -> username = $username;
$this -> password = $password;
$this -> options = $options;
}
private function getRealPDO()
{
if (is_null ($this -> realPDO))
{
$this -> realPDO = new PDO ($this -> dsn, $this -> username, $this -> password, $this -> options);
}
return $this -> realPDO;
}
// We're only implementing exec for brevity but you have to do this for all public methods of PDO
public function exec ($sql)
{
$retries = 0;
while (true)
{
try
{
return $this -> getRealPDO() -> exec ($sql);
}
catch (PDOException $ex)
{
$this -> realPDO = NULL;
if (++$retries > 5)
{
// We've passed our retry limit
throw $ex;
}
}
}
}
}
Ponieważ klasa ta rozciąga PDO może być stosowany wszędzie tam, gdzie można zastosować ogólną klasę PDO.
Jak widać, to podejście da ci kilka ponownych prób, zanim metoda exec() zrezygnuje, pozwalając na ponowne połączenie po przejściowych błędach (jest to tylko demonstracja i brakuje niektórych funkcji, których potrzebowałaby prawdziwa implementacja, np. powstrzymywanie pomiędzy ponownymi próbami, odpowiednim rejestrowaniem błędów itp.). Takie podejście wymagałoby również sprawdzenia specyfiki wyjątku PDO, ponieważ nie chcesz, aby błędy składni MySQL powodowały resetowanie połączenia i próbę ponowienia. Chcesz tylko, aby to się stało w takich sytuacjach, jak "Serwer zniknął".
Jak można zauważyć, wdrożenie wszystkich metod PDO prokuratorii stałoby się ciężkim zadaniem, choć trzeba to zrobić tylko wtedy, gdy prawdopodobnie warto zainwestować w ten wysiłek.
Istnieje jednak znacznie większy problem, który jest dość powszechnym problemem dla każdego kodu, który komunikuje się z bazą danych, a nie tylko z PDO. Co się stanie, jeśli połączenie zostanie utracone w trakcie transakcji? Nie chcesz, aby twój skrypt ponownie się łączył i odbierał miejsce, w którym zostało przerwane, ponieważ cała praca wykonana do ostatniego zatwierdzenia zostanie utracona i istnieje duże prawdopodobieństwo, że nie byłoby logiczne, aby wznowić po ponownym połączeniu będziesz musiał zacząć od nowa. Dlatego prawdopodobnie chciałbyś, aby cały skrypt zaczął się od nowa, a próba ponownego połączenia nie miałaby sensu. Prawdopodobnie dlatego mySQLI obsługuje ponowne łączenie, ale PDO tego nie robi.
Jeśli twój skrypt odczytuje tylko lub nietransakcyjne zapisy, to powyższe podejście ma wartość, ale jak tylko wyrzucisz transakcje do miksu, w rzeczywistości jesteś o wiele lepiej bez próby ponownego połączenia.
- 1. PDOStatement do json
- 2. PHP mysqli reconnect problem
- 3. Jak uzyskać typy numeryczne z MySQL przy użyciu PDO?
- 4. PHP MySQL PDO lastInsertID powoduje błąd krytyczny
- 5. Układ Android z widocznością GONE
- 6. PDO i MySQL "między"
- 7. PDO queryString z powiązanymi danymi
- 8. Sterownik MySQL PDO na Macu
- 9. PDOstatement (MySQL): wstawienie wartości 0 do bitu (1) powoduje wyświetlenie 1 w tabeli
- 10. perl dbi reconnect on disconnect
- 11. Jak animować View.setVisibility (GONE)?
- 12. Aktualizacja kwerendy z PDO i MySQL
- 13. MySql PDO połączenie z bazą danych
- 14. Uzyskiwanie identyfikatora wkładki z wkładką PDO MySQL
- 15. Ustawienie PDO/MySQL LIMIT z Nazwany Placeholder'ów
- 16. Jak mogę sprawdzić połączenie MySQL PDO pod kątem błędów PRZED uruchomieniem zapytania?
- 17. mysql PDO jak związać LIKE
- 18. Call to metoda niezdefiniowany PDOStatement :: setFetchMode()
- 19. Jak mogę obejrzeć przygotowane oświadczenie PDO SQL
- 20. Skrypt MySQL z wycofywaniem przy błędzie
- 21. Django, po aktualizacji: serwer MySQL zniknęło
- 22. PDO - Niepoprawny numer parametru
- 23. Problemy z używaniem PDO po raz pierwszy
- 24. Nie można połączyć się z serwerem MySQL przy użyciu PDO
- 25. PDO + MySQL i złamane kodowanie UTF-8
- 26. Złap i wyjmij błędy mysql pdo
- 27. mysql pdo transakcja i przechowywanie sesji
- 28. zwraca jedną wartość z bazy danych z mysql php pdo
- 29. PHP PDO z SQL Server i przygotowane oświadczenia
- 30. Czy widoki "GONE" są zawyżone?
Rozumiem twój pomysł, ale naprawdę powinieneś dodać kod do swojej odpowiedzi. –
Co się stanie, jeśli prowadzisz zestaw zapytań, które są a) transakcyjne, i b) zdarza się, że trwa dłużej niż TTL? – GordonM