Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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...";
}
?>Em uma pesquisa no que fiz, no php 5.5 +
da para ver quais inserts falharam no bloco finally
try{
//
} catch (PDOException $exception) {
$banco->rollback();
printf('Não foi possível realizar a operação: %s' , $exception);
} finally {
// echo erro na sql tal
}
Não se esqueça de adicionar
$banco->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
ANTES de iniciar a transação
>
Não se esqueça de adicionar
$banco->setAttribute(PDO::ATTR_AUTOCOMMIT, false);
ANTES de iniciar a transação
Não há essa necessidade, beginTransaction automaticamente seta auto commit como false.
Valeu mesmo Williams Duarte pelas dicas, fiz aqui e deu tudo certo, muito obrigado mesmo.
Há um porém em utilizar o bloco finally para tratar as sqls que deram errado, pois o finally é sempre executado, mesmo que nenhum erro aconteça. Logo, se é um tratamento específico de erros das queries, esse tratamento deve ser feito no catch.
#6
Quem te ajudou foi o Gabriel Heming :grin:
Há um porém em utilizar o bloco finally para tratar as sqls que deram errado, pois o finally é sempre executado, mesmo que nenhum erro aconteça. Logo, se é um tratamento específico de erros das queries, esse tratamento deve ser feito no catch.
Sei!!! Mas era uma forma diferente, vi em um post em um fórum gringo, não me recordo a url, mas era uma forma diferente, pega o erro do catch e disparava um email dentro do finally, bem interessante, mas aqui para mim já não rola 5.4
Sim o Gabriel Heming também! :)
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
} catch (PDOException $exception) {