Transações e auto-commit

Agora que você está conectado via PDO, você deve entender como o PDO gerencia as operações antes de começar a emitir consultas. Se você nunca encontrou antes transacções, que oferecem quatro características principais: Atomicidade, Consistência, Isolamento e Durabilidade (ACID). Em termos leigos, qualquer trabalho realizado em uma operação, mesmo se for realizada em etapas, está garantido para ser aplicada ao banco de dados com segurança e sem interferência de outras conexões, quando é cometida. trabalhos transacionais também podem ser automaticamente desfeitos a seu pedido (desde que você já não tenha comitado), que faz tratamento de erros em seus scripts mais fácil.

As transações são normalmente implementadas por "salvar-se" o seu lote de mudanças a serem aplicadas de uma só vez, o que tem o bom efeito colateral de melhorar drasticamente a eficiência dessas atualizações. Em outras palavras, as transações podem tornar seus scripts mais rápidos e potencialmente mais robustos (você ainda precisa usá-los corretamente para aproveitar esse benefício).

Infelizmente, nem todo banco de dados oferece suporte a transações, assim o PDO precisa ser executado no que é conhecido como "auto-commit", quando você abre a conexão. Modo auto-commit significa que cada consulta que você executa tem a sua própria transação implícita, se o banco de dados suporta isso, ou não. Se você precisar de uma transação, você deve usar o PDO::beginTransaction() para iniciar uma transação. Se o subjacente driver não suporta transações, um PDOException será lançado (independentemente de suas configurações de tratamento de erros: esta é sempre uma condição de erro grave). Quando você estiver em uma transação, você pode usar PDO::commit() ou PDO::rollback() para terminá-lo, dependendo do sucesso ao executar o código durante a transação.

Aviso:
PDO apenas verifica a capacidade de operação em nível de driver. Se a condição de execução, implicar que as operações não estiverem disponíveis, PDO::beginTransaction() ainda retornará TRUE sem erro se o servidor de banco de dados aceitar o pedido para iniciar uma operação.
Um exemplo disso seria tentar usar transações em tabelas em um banco de dados MySQL.

Quando o script termina ou quando uma conexão está prestes a ser fechada, se você tiver uma transação pendente, o PDO automaticamente a reverte. Esta é uma medida de segurança para ajudar a evitar inconsistências nos casos em que o script é encerrado inesperadamente - se você não explicitamente confirmar a transação, então supõe-se que algo deu errado, assim a reversão é feita para a segurança dos seus dados.

Aviso:
A reversão automática só acontece se você iniciar a transação via PDO::beginTransaction(). Se você manualmente emitir uma consulta que começa numa operação, o PDO não tem nenhuma maneira de saber sobre isso e, portanto, não pode revertê-la se algo de errado acontecer.

Exemplo de uma execução de um lote em uma transação:

No exemplo a seguir, vamos assumir que estamos criando um conjunto de entradas para um novo funcionário, que tenha sido atribuído um número de identificação 23. Além de inserir os dados básicos dessa pessoa, também precisamos gravar o seu salário. É muito simples de fazer duas atualizações separadas, mas colocando-os dentro do PDO::beginTransaction() e PDO::commit(), estamos garantindo que ninguém será capaz de ver essas mudanças, até que sejam concluídas. Se algo der errado, o bloco catch reverte todas as alterações feitas desde o início da transação e em seguida, imprime uma mensagem de erro.

Código:

<?php
try {
  $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',
      array(PDO::ATTR_PERSISTENT => true));
  echo "Connectedn";
} catch (Exception $e) {
  die("Unable to connect: " . $e->getMessage());
}

try { 
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $dbh->beginTransaction();
  $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
  $dbh->exec("insert into salarychange (id, amount, changedate)
      values (23, 50000, NOW())");
  $dbh->commit();
 
} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}
?>


Você não está limitado a fazer atualizações em uma transação, você também pode emitir consultas complexas para extrair dados e, possivelmente, usar essa informação para construir mais atualizações e consultas, enquanto a transação está ativa, você está garantido que ninguém mais pode fazer alterações enquanto você está no meio de seu trabalho. Para ler mais sobre transações, consulte a documentação fornecida pelo seu servidor de banco de dados.

Até ;-)