Transações no PDO, garantindo que tudo vai ser executado Artigo

Conheça os cursos gratuitos do WebDevBr! - Inscreva-se!


Este artigo foi publicado a 2 anos, 6 meses, 4 dias atrás.

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!


Cursos relacionados


* Parcelamento apenas cartão de crédito! Pode haver uma pequena variação no parcelamento em relação a simulações apresentadas!