Boa noite pessoal, sou iniciante em PDO em PHP e estou com uma dificuldade em transações, gostaria de saber se alguém pode me ajudar neste ponto abaixo:
Quero colocar vários INSERT num único bloco de transação pois caso ocorra algum erro na gravação de alguma tabela todos os INSERT devem ser cancelados (rollback).
Segue o meu código:
<?php
header("Content-Type: text/html; charset=UTF-8",true);
include("bd/conexao_pdo.php");
$banco = conectar();
$txtUf = $_POST['idUf'];
$txtCidade = mb_strtoupper($_POST['idCidade']);
$txtBairro = mb_strtoupper($_POST['idBairro']);
$sql = 'INSERT INTO tb_cidade (cid_nome, fk_id_uf_tb_cidade) VALUES (:cidade, :fk_uf)';
$sql1 = 'INSERT INTO tb_bairro (bai_nome, fk_id_cidade_tb_bairro) VALUES (:bairro, :fk_cidade)';
$banco->beginTransaction();
$create_cid = $banco->prepare($sql);
$create_cid->bindValue(':cidade', $txtCidade, PDO::PARAM_STR);
$create_cid->bindValue(':fk_uf', $txtUf, PDO::PARAM_INT);
$create_cidade = $create_cid->execute();
if (!$create_cidade) {
$banco->rollBack();
die("Erro ao gravar Cidade");
} else {
$idCidade = $banco->lastInsertId();
$banco->commit();
}
$banco->beginTransaction();
$create_bai = $banco->prepare($sql1);
$create_bai->bindValue(':bairro', $txtBairro, PDO::PARAM_STR);
$create_bai->bindValue(':fk_cidade', $idCidade, PDO::PARAM_INT);
$create_bairro = $create_bai->execute();
if (!$create_bairro) {
$banco->rollBack();
die("Erro ao gravar Bairro");
} else {
$idBairro = $banco->lastInsertId();
$banco->commit();
echo "Dados gravados com sucesso...";
}
?>
Se você quiser que todos os inserts sejam revertidos em caso de erro, utilize apenas uma transaction e exceptions para tratar os erros dos inserts.
try {
$banco->setAttribute(PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION);//Ativa o lançamento de exceptions para erros
$banco->beginTransaction();
$create_cid = $banco->prepare($sql);
$create_cid->bindValue(':cidade', $txtCidade, PDO::PARAM_STR);
$create_cid->bindValue(':fk_uf', $txtUf, PDO::PARAM_INT);
$create_cid->execute();//Não há necessidade em verificar o retorno, se não inserir, será lançada uma exception
$create_bai = $banco->prepare($sql1);
$create_bai->bindValue(':bairro', $txtBairro, PDO::PARAM_STR);
$create_bai->bindValue(':fk_cidade', $idCidade, PDO::PARAM_INT);
$create_bai->execute();//Não há necessidade em verificar o retorno, se não inserir, será lançada uma exception
$banco->commit();
} catch (PDOException $exception) {
$banco->rollback();
printf('Não foi possível realizar a operação: %s' , $exception);
}