Transactions são a maneira que o PDO do PHP tem de garantir que várias queries sejam executadas e em caso de erro, nenhuma será, simples assim! Imagine que você tem um script que precise executar um query baseado em outro, existem muitos exemplos a se pensar, vamos trabalhar com a ideia (até um clichê) que você tem um sistema financeiro que vai fazer a transferência entre contas, então temos:
$valor= 50;
$sql = [
'select'=>'SELECT valor FROM financeiro WHERE id=:id;',
'update'=>'UPDATE financeiro SET valor=:valor WHERE id=:id;'
];
// Conexão com o banco com retorno na variável $pdo
//verifica o saldo
$sth = $pdo->prepare($sql['select']);
$sth->execute([':id'=>1]);
$conta1 = $sth->fetch(PDO::FETCH_ASSOC);
$sth->execute([':id'=>2]);
$conta2 = $sth->fetch(PDO::FETCH_ASSOC);
if ($conta1['valor'] >= $valor) {
//calcula valores do deposito na conta final e saque
//da conta que está enviando o dinheiro
$saque = $conta1['valor']-$valor;
$deposito = $conta2['valor']+$valor;
//executa o saque
$sth = $pdo->prepare($sql['update']);
$sth->execute([':id'=>1, ':valor'=>$saque]);
//executa o depósito
$sth = $pdo->prepare($sql['update']);
$sth->execute([':id'=>2, ':valor'=>$deposito]);
}
O problema é que no momento de executar o saque e o depósito não há como garantir que tudo dará certo, você pode ter um problema no servidor, um problema no próprio script ou outro que faça com que só o saque seja executado (lei de Murphi, rsrs), o valor então vai sumir e nunca chegar a conta final, precisamos garantir que o processo seja executado com sucesso, afinal, como você vai dar conta do valor que sumiu?
Vamos tentar novamente.
Gostou deste artigo?
Receba atualizações semanais com novos artigos do WebDevBr e outras dicas!
$valor= 50;
$sql = [
'select'=>'SELECT valor FROM financeiro WHERE id=:id;',
'update'=>'UPDATE financeiro SET valor=:valor WHERE id=:id;'
];
// Conexão com o banco com retorno na variável $pdo
//verifica o saldo
$sth = $pdo->prepare($sql['select']);
$sth->execute([':id'=>1]);
$conta1 = $sth->fetch(PDO::FETCH_ASSOC);
$sth->execute([':id'=>2]);
$conta2 = $sth->fetch(PDO::FETCH_ASSOC);
if ($conta1['valor'] >= $valor) {
//calcula valores do deposito na conta final e saque
//da conta que está enviando o dinheiro
$saque = $conta1['valor']-$valor;
$deposito = $conta2['valor']+$valor;
$pdo->beginTransaction();
//executa o saque
$sth = $pdo->prepare($sql['update']);
$sth->execute([':id'=>1, ':valor'=>$saque]);
//executa o depósito
$sth = $pdo->prepare($sql['update']);
$sth->execute([':id'=>2, ':valor'=>$deposito]);
$pdo->commit();
}
Agora temos dois novos comandos, o beginTransaction() e o commit(), ele garante que todas as queries serão executadas ou nenhuma será.
PDO::beginTransaction
O método beginTransaction informa o início de uma transação no PDO, ou seja, a partir daquele ponto, todas as queries dependem uma da outra e precisam ser executadas todas com sucesso, se uma falhar, então devemos parar a execução.
Para maiores informações acesse este link da documentação.
PDO::commit
O commit tenta executar todas as queries se uma falhar ele para e não executa nenhuma delas, o que garante segurança e estabilidade a nossa aplicação. Você pode pegar o valor retornado por ele para verificar se tudo deu certo, por exemplo:
if ($pdo->commit()) {
echo 'Executado com sucesso';
} else {
echo 'Não pode ser executado';
}
Sim, o commit retorna true em caso de sucesso e false se não der certo.
Para maiores informações acesse este link da documentação.
Conclusão
Transações são uma excelente forma de garantir que tudo vai bem na sua aplicação e manter a integridade dos dados, isso é fundamental, lembre-se disso!