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

_Echo_

Новичок
Всем доброго времени суток!
Возник вопрос по поводу отлавливания Exception после разъединения с базой данных.
Есть такой код:
PHP:
<?php

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

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

try{
 
    $sql = "INSERT INTO user (name) VALUES (?)";
 
    $result = $pdo->prepare($sql);
 
    foreach($names as $key=>$name){
        $pdo->beginTransaction();
      
        echo $name;
        if($key == 1){
       //Здесь эмуляция разрыва соединения с базой данных
            $pdo = NULL;
        }
      
        $result->execute([$name]);
        $pdo->commit();
    }
 
}catch(PDOException $e){
 
    $pdo->rollBack();
    echo "Ошибка: " . $e->getMessage();
}
?>
Предположим мне нужно отследить, на каком значении массива произошел сбой,
т. е. какое значение не занеслось в БД.
Сейчас скрипт выдает Fatal Error и не попадает в блок catch.
Даже если PDO автоматически делает rollBack, то как отследить когда произошел сбой?
 
Последнее редактирование модератором:

флоппик

promotor fidei
Команда форума
Партнер клуба
@Adelf, ты не туда смотришь. Посмотри, где происходит старт транзакции, где коммит, где роллбэк, и перечитай последние предложения)
 

Adelf

Administrator
Команда форума
т. е. какое значение не занеслось в БД.
не занеслись все значения начиная с beginTransaction. в этом и смысл транзакции.

@флоппик, у меня сегодня туго с понимаем вопросов. да и с пдо я никогда не работал напрямую. Вдруг они там не откатывают их автоматом...
 

флоппик

promotor fidei
Команда форума
Партнер клуба
не занеслись все значения начиная с beginTransaction. в этом и смысл транзакции.

@флоппик, у меня сегодня туго с понимаем вопросов. да и с пдо я никогда не работал напрямую. Вдруг они там не откатывают их автоматом...
Неа. У него начало транзацкий внутри цикла :D
 

_Echo_

Новичок
Хотелось бы вот такой вариант:

<?php

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

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

try{

$sql = "INSERT INTO user (name) VALUES (?)";

$result = $pdo->prepare($sql);

foreach($names as $key=>$name){
$pdo->beginTransaction();

if($key == 1){
//Здесь эмуляция разрыва соединения с базой данных
throw new Exception("Fatal Error...!!! No record:/".$name."/");
//$pdo = NULL;
}

$result->execute([$name]);
$pdo->commit();
}

}catch(PDOException $e){

$pdo->rollBack();
echo "Ошибка: " . $e->getMessage();
}

?>
 

fixxxer

К.О.
Партнер клуба
У тебя безо всяких транзакций словится исключение в момент сбоя.
 

AnrDaemon

Продвинутый новичок
Хотелось бы вот такой вариант:

<?php

$pdo = new PDO('mysql:host=localhost;dbname=practica', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Слишком поздно включаете эксепшены.

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

try{

$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."/");
//$pdo = NULL;
"$pdo = null;" удаляет текущую ссылку на соединение, но соединение не факт что закроется.

}

$result->execute([$name]);
}

}catch(PDOException $e){
echo "Ошибка: " . $e->getMessage();
}
 

Yoskaldyr

"Спамер"
Партнер клуба
Если интересует частичный откат транзакций то надо смотреть в сторону SAVEPOINT. Но тут куча нюансов, не все базы умеют или не все движки в пределах базы и т.д. Да и все равно придется свою обертку писать над PDO для удобства. А так вещь конечно полезная и удобная
 

Yoskaldyr

"Спамер"
Партнер клуба
@grigori, Если брать все популярное, то проблем не будет, но всякая экзотика типа старого SQLite, или новых движков mysql/maria (тот же распиаренный MyRocks не умеет)
 

Фанат

oncle terrible
Команда форума
Если интересует частичный откат транзакций то надо смотреть в сторону SAVEPOINT. Но тут куча нюансов, не все базы умеют или не все движки в пределах базы и т.д. Да и все равно придется свою обертку писать над PDO для удобства. А так вещь конечно полезная и удобная
Дав не интересует его никакой частичный откат
он просто в принципе не понимает, как работают транзакции
и пихает совершенно не к месту

Ему ПРОСТО надо сказать, чтобы убрал транзакцию из кода.
И трай с кетчем заодно.

Вы, блин, читайте, что @fixxer пишет.
После него добавлять ничего не нужно.
 

Фанат

oncle terrible
Команда форума
Хотелось бы вот такой вариант:
Тебе хотелось бы вот такой
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]);
}
он делает ровно то что тебе надо
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Последнее редактирование:

Фанат

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