Как работать с транзакциями в PDO.

AnrDaemon

Продвинутый новичок
Не сочтите за труд процитировать аргументацию? Ибо мои тесты показывают, что даже в конструкторе это делать уже поздно.
 

Фанат

oncle terrible
Команда форума
исходники например

На тесты я бы посмотрел, поскольку несколько раз слышал жалобы на то, что в некоторых случаях пдо выдает варнинг тупо в стдаут, игнорируя настройки пхп, но никогда не видел этого в живую.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Фанат, ты хочешь сказать, что вместо exception-ов надо отлавливать ошибки? :) или что исключения надо включать до соединения? :)

у ТС проблема не в "поздно включает", а в "поздно ловит" - конструктор PDO тоже бросается
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
ты хочешь сказать, что вместо exception-ов надо отлавливать ошибки?
Я хочу сказать, что описанное поведение никак не отлавливается вообще, поскольку это фактически даже не ошибка, а тупо вывод в стдаут. Ссылку щас не найду.

А проблему ТС-а я уже описал - ему вообще ничего ловить не нужно, ни рано, ни поздно
 

_Echo_

Новичок
Тебе хотелось бы вот такой
PHP:
<?php

$pdo = new PDO('mysql:host=localhost;dbname=practica', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$names = ['Aaa', 'Bbb', 'Ccc'];

$sql = "INSERT INTO user (name) VALUES (?)";
$result = $pdo->prepare($sql);

foreach($names as $key=>$name){
    if($key == 1){
        throw new Exception("Fatal Error...!!! No record:/".$name."/");
    }
    $result->execute([$name]);
}
он делает ровно то что тебе надо
Да все понятно уже!
Спасибо за помощь.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Гриш, не надо делать из меня идиота.
Будет время - найду ту ветку, покажу. А тупо погыгыкать найди себе какой-нибудь другой повод.
так, у нас перепонимание того, чего нет.
обработка ошибок и логи - это серьезный вопрос, в каждом проекте делается по-своему, и чаще всего сначала забивают, потом героически превозмогают

я сейчас специально переделываю вывод приложений в stderr чтобы запускать в контейнерах, и это не то чтоб совсем тривиально в случае с php-приложением
 

AnrDaemon

Продвинутый новичок
а шо с этим не так?
Да, конструктор бросает исключения сам по себе, независимо от режима, да, но… В 5.6 он не перехватывает ошибок более низкого уровня.
Код:
PHP Warning:  PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Этот хост неизвестен.  in …/pdo-exceptions.php on line 3
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Этот хост неизвестен. ' in …/pdo-exceptions.php:3
Stack trace:
#0 …/pdo-exceptions.php(3): PDO->__construct('mysql:host=none...')
#1 {main}
  thrown in …/pdo-exceptions.php on line 3
 

fixxxer

К.О.
Партнер клуба
Понятное дело, что warning в php_network_getaddresses никуда не денется. Непонятно, чем это мешает.
Существует два варианта:
1) реалистичный - warning-и завернуты в исключения, словится ErrorException
2) теоретический - warning-и не завернуты в исключения, залогируется warning и потом словится PdoException

В итоге один фиг. Проблему тут вижу только одну - если ты ловишь PDOException и делаешь что-то разумное, а по факту там будет ErrorException и улетит в глобальный обработчик. Но я не очень себе представляю, чего там разумного можно сделать в catch-е на конструктор PDO.

Кстати, в семерке warning-а не наблюдаю.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Почему же никуда не денется?
Прекрасно девается в семёрке
Ну там просто добавили костылик вида
PHP:
zend_replace_error_handling()
...
zend_restore_error_handling()
Но на практике я разницы все равно не вижу. Допустим, у меня есть код вида
PHP:
try {
    $pdo = new PDO(...);
} catch (PDOException $e) {

}
Что такое разумное я мог бы сделать внутри этого catch?
 

fixxxer

К.О.
Партнер клуба
Я об этом подумал и не счел это разумным. :)

Хотя могут быть редкие случаи, когда таки да. Ну тогда надо просто помнить, что надо ловить \Exception.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в абсолютном большинстве случаев просто подключиться к другому серверу при сбое подключения невозможно:
  • подключение к мастеру нельзя заменить на подключение к слейву
  • мастер-мастер репликация требует заранее проектировать структуру - заменять auto_increment на uuid
failover решается на уровне service locator / orchestration, и архитектура в принципе строится с расчетом на сбой приложения
 
Сверху