Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
O primeiro insert deu certo.
O segundo insert deu erro.
O rollback não foi feito, o primeiro insert foi inserido na base. Como eu faço para quando der erro em qualquer insert dar rollback em todos os inserts ?
$produto_id = split(";", $_GET["produto_id"]);
$produto_quantidade = split(";", $_GET["produto_quantidade"]);
$db = new PDO('mysql:host=localhost;port=3306;dbname=namorofalso', 'root', 'Altera1janio1');
try {
/ ------------------------------------ LISTA DADOS DOS ITENS DOS PRODUTOS COMPRADOS ------------------------------------------------------- /
$pedido_valor = 0;
for($index = 0; $index < count($produto_id); $index++) {
$stmt = $db->prepare("SELECT * FROM tb_produto WHERE produto_id=:produto_id");
$stmt->bindValue(':produto_id', $produto_id[$index], PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$pedido_valor += ($rows[0]["produto_valor"] * $produto_quantidade[$index]);
$item = array("produto_id" => $rows[0]["produto_id"], "item_nome" => $rows[0]["produto_nome"],
"item_valor" => $rows[0]["produto_valor"]);
}
/ -------------------------------- CADASTRA O PEDIDO E OS ITENS DOS PEDIDOS COMPRADOS ----------------------------------------------------- /
$db->beginTransaction();
//PEDIDO
$db->exec('INSERT INTO tb_pedido(pedido_valor) VALUES('. $pedido_valor .')');
$pedido_id = $db->lastInsertId();
//ITEM DO PEDIDO
for($index = 0; $index < count($item); $index++)
$db->exec('INSERT INTO tb_pedido_item(pedido_id, item_valor, produto_id) VALUES("$pedido_id", "$item[$index]["item_valor"]", "$item[$index]["produto_id"]")');
$db->commit();
}
catch (PDOException $e) {
$db->rollBack();
echo $e->getMessage();
}$db = new PDO('mysql:host=localhost;port=3306;dbname=namorofalso', 'root', 'Altera1janio1');try {
/ ------------------------------------ LISTA DADOS DOS ITENS DOS PRODUTOS COMPRADOS ------------------------------------------------------- /
$pedido_valor = 0;
for($index = 0; $index < count($produto_id); $index++) {
$stmt = $db->prepare("SELECT * FROM tb_produto WHERE produto_id=:produto_id");
$stmt->bindValue(':produto_id', $produto_id[$index], PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$pedido_valor += ($rows[0]["produto_valor"] * $produto_quantidade[$index]);
$item = array("produto_id" => $rows[0]["produto_id"], "item_nome" => $rows[0]["produto_nome"],
"item_valor" => $rows[0]["produto_valor"]);
} $db->beginTransaction();
//PEDIDO
$db->exec('INSERT INTO tb_pedido(pedido_valor) VALUES('. $pedido_valor .')');
$pedido_id = $db->lastInsertId();
//ITEM DO PEDIDO
//for($index = 0; $index < count($item); $index++)
$db->exec('INSERT INTO tb_pedido_item(pedido_id, item_valor, produto_id) VALUES("$pedido_id", "$item[0]["item_valor"]", "$item[0]["produto_id"]")');
$db->commit();
} $db->rollBack();
echo $e->getMessage();
}
O segundo insert não está sendo executado e não está entrando no catch.
Cara não tinha parado pra analisar bem o seu código, mas eu não sei então o que você disse que está inserindo nem para o primeiro insert. Pra começa aspas simples iriam pegar o texto literal e não o valor das variáveis. Já que você esta usando PDO não passe os valores dessa forma.
Use assim, exemplo:
$pdo->beginTransaction();
$stmt = $pdo->prepare('INSERT INTO tabela(nome_campo) VALUES(:campo)');
//passe os valores nomeados
$stmt->bindValue(':campo', 'valor');
$stmt->execute();
$pdo->commit();
A questão de não estar lançando exceção possivelmente é porque você não definiu para que sua conexão faça isso.
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Obrigado Marcielo, era isso mesmo.
Oras, você já fez, iniciando a transação antes de começar os inserts, cada insert feito até então não será persistido na base, estará apenas em memória, será persistido literalmente com um commit(), mas caso ocorra alguma falha em algum será lançado uma exceção e cairá no catch, onde você já está chamando o rollback() limpando esse buffer de inserts.
Uma forma de se testar é, faça alguns sem o for e provoque algum erro no sql.
Agora o que você poderia melhor aí, é separar a parte de listagens das persistências, trate separadamente porque se ocorre uma falha em select ele também chamará o rollback().