При установлении соединения с базой данных с использованием PDO, должен ли каждый раз использовать атрибут PDO PDO:: ATTR_PERSISTENT? В нем говорится, что это создает постоянное соединение для этого пользователя и будет захватывать это же соединение вместо повторного установления нового при каждом запросе подключения к базе данных. Почему это не по умолчанию? Есть ли причина не использовать его?
Должен ли использоваться PDO:: ATTR_PERSISTENT каждый раз?
Ответ 1
Проблема с постоянными подключениями заключается в том, что количество подключений, доступных для MySQL, ограничено. Если что-то пойдет не так, и соединение не закрыто, сервер собирается оставить его открытым в течение длительного времени. Если на сервере заканчиваются соединения, то каждое приложение, привязанное к нему, будет недоступно, пока кто-то не вмешается.
Вероятно, вы можете ожидать, что что-то пойдет не так, время от времени, и при неправильных обстоятельствах проблема чрезмерного использования ресурсов может протекать через несколько месяцев, если не будет замечена, что приведет к очень постепенному ухудшению производительности и увеличению использования системы со временем (все без усиления).
Вот одна хорошая статья, которая может вам помочь. Он фокусируется на MySQL, но большинство подобных мыслей могут быть обобщены по всему спектру СУБД.
Ответ 2
Если вы не обрабатываете транзакцию правильно, это может привести к "новому" постоянному соединению уже в транзакции, что может вызвать хаос.
Просто один простой случай, вызванный следующим кодом:
<?php
$pdo = getCustomPersistantPDO();
$pdo->beginTransaction();
if( rand() % 2 === 0 ) {
//simulate a poorly handled error
exit();
}
$pdo->commit();
?>
Запрос 1:
(starts w/o a transaction open)
openTransaction
incorrectly handled error
(never closes transaction)
Запрос 2:
(start w/ a transaction open, because it was not closed in the previous connection.)
openTransaction -> fails due to already open
Кстати, правильная версия примера:
<?php
$pdo = getCustomPersistantPDO();
$pdo->beginTransaction();
if( rand() % 2 === 0 ) {
//simulate a correctly handled error
$pdo->rollBack();
exit();
}
$pdo->commit();
?>