<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.pdo.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'pdo.transactions.php',
    1 => 'Transa&ccedil;&otilde;es e confirma&ccedil;&atilde;o autom&aacute;tica (auto-commit)',
    2 => 'Transa&ccedil;&otilde;es e confirma&ccedil;&atilde;o autom&aacute;tica (auto-commit)',
  ),
  'up' => 
  array (
    0 => 'book.pdo.php',
    1 => 'PDO',
  ),
  'prev' => 
  array (
    0 => 'pdo.connections.php',
    1 => 'Conex&otilde;es e gerenciamento de conex&otilde;es',
  ),
  'next' => 
  array (
    0 => 'pdo.prepared-statements.php',
    1 => 'Declara&ccedil;&otilde;es preparadas e procedimentos armazenados',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'reference/pdo/transactions.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="pdo.transactions" class="chapter">
 <h1 class="title">Transações e confirmação automática (auto-commit)</h1>

 <p class="para">
  Agora que você está conectado via PDO, é necessário entender como o PDO
  gerencia transações antes de começar a emitir consultas. Se você nunca
  encontrou transações antes, elas oferecem 4 recursos principais: Atomicidade,
  Consistência, Isolamento e Durabilidade (ACID). Em termos simples, qualquer trabalho
  realizado em uma transação, mesmo que seja feito em etapas, é
  garantido de ser aplicado ao banco de dados com segurança e sem interferência
  de outras conexões, quando é confirmado. O trabalho transacional também pode
  ser desfeito automaticamente a seu pedido (desde que você ainda não tenha
  confirmado), o que facilita o tratamento de erros em seus scripts.
 </p>
 <p class="para">
  As transações são tipicamente implementadas &quot;salvando&quot; seu lote de
  alterações para serem aplicadas de uma vez; isso tem o efeito colateral agradável de
  melhorar drasticamente a eficiência dessas atualizações. Em outras palavras,
  transações podem tornar seus scripts mais rápidos e potencialmente mais robustos
  (ainda é necessário usá-los corretamente para obter esse benefício).
 </p>
 <p class="para">
  Infelizmente, nem todos os bancos de dados suportam transações, então o PDO precisa
  rodar no que é conhecido como modo &quot;auto-commit&quot; quando você abre a
  conexão pela primeira vez. O modo auto-commit significa que cada consulta que você
  executa tem sua própria transação implícita, se o banco de dados suportar, ou nenhuma transação
  se o banco de dados não suportar transações. Se você precisar de uma transação,
  você deve usar o método <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> para
  iniciá-la. Se o driver subjacente não suportar transações, uma
  PDOException será lançada (independentemente das suas configurações de tratamento de erro:
  essa é sempre uma condição de erro grave). Uma vez que você está em uma transação,
  você pode usar <span class="methodname"><a href="pdo.commit.php" class="methodname">PDO::commit()</a></span> ou
  <span class="methodname"><a href="pdo.rollback.php" class="methodname">PDO::rollBack()</a></span> para finalizá-la, dependendo do sucesso
  do código que você executou durante a transação.
 </p>
 <div class="warning"><strong class="warning">Aviso</strong>
  <p class="para">
   O PDO verifica apenas as capacidades de transação no nível do driver. Se certas
   condições de tempo de execução significarem que transações estão indisponíveis,
   <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> ainda retornará <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>
   sem erro se o servidor de banco de dados aceitar a solicitação para iniciar uma
   transação.
  </p>
  <p class="para">
   Um exemplo disso seria tentar usar transações em tabelas MyISAM em
   um banco de dados MySQL.
  </p>
 </div>
 <div class="warning"><strong class="warning">Aviso</strong>
  <p class="para">
   <em>Confirmações Implícitas com Instruções DDL:</em>
   Alguns bancos de dados emitem automaticamente um
   <code class="literal">COMMIT</code> implícito quando uma instrução de Linguagem de Definição
   de Banco de Dados (DDL), como <code class="literal">DROP TABLE</code> ou <code class="literal">CREATE TABLE</code>,
   é executada dentro de uma transação. Isto significa que quaisquer modificações feitas na
   mesma transação serão <em>confirmadas automaticamente</em> e não poderão
   ser revertidas.
  </p>
  <p class="para">
   <code class="literal">MySQL</code> e <code class="literal">Oracle</code> são exemplos de bancos de dados que
   exibem este comportamento.
  </p>
 </div>
 <p class="para">
  <div class="example" id="example-1">
   <p><strong>Exemplo #1 Exemplo de Confirmação Implícita</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$pdo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">beginTransaction</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$pdo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exec</span><span style="color: #007700">(</span><span style="color: #DD0000">"INSERT INTO users (name) VALUES ('Rasmus')"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$pdo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exec</span><span style="color: #007700">(</span><span style="color: #DD0000">"CREATE TABLE test (id INT PRIMARY KEY)"</span><span style="color: #007700">); </span><span style="color: #FF8000">// aqui ocorre um COMMIT implícito<br /></span><span style="color: #0000BB">$pdo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">rollBack</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Isto NÃO irá desfazer as instruções INSERT/CREATE no MySQL ou no Oracle<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <em>Melhores Práticas:</em> Evite executar instruções DDL dentro de transações
  quando usar banco de dados que têm este comportamento. Se necessário, separe as operações DDL
  da lógica das transações.
 </p>
 <p class="para">
  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 reverterá.
  Esta é uma medida de segurança para ajudar a evitar inconsistências nos casos em que
  o script termina inesperadamente--se você não confirmou explicitamente a
  transação, então é assumido que algo deu errado, então o rollback
  é executado para a segurança de seus dados.
 </p>
 <div class="warning"><strong class="warning">Aviso</strong>
  <p class="para">
   O rollback automático só acontece se você iniciar a transação via
   <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span>. Se você emitir manualmente uma
   consulta que inicia uma transação, o PDO não tem como saber sobre isso e
   assim não pode revertê-la se algo ruim acontecer.
  </p>
 </div>
 <p class="para">
  <div class="example" id="example-2"><p><strong>Exemplo #2 Executando um lote em uma transação</strong></p>
   <div class="example-contents"><p>
    No exemplo a seguir, vamos assumir que estamos criando um conjunto de
    entradas para um novo funcionário, que recebeu um número de ID 23.
    Além de inserir os dados básicos para essa pessoa, também precisamos
    registrar seu salário. É bastante simples fazer duas atualizações separadas,
    mas ao envolvê-las nas chamadas
    <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> e
    <span class="methodname"><a href="pdo.commit.php" class="methodname">PDO::commit()</a></span>, estamos garantindo que ninguém
    mais poderá ver essas alterações até que elas estejam completas. Se
    algo der errado, o bloco catch reverte todas as alterações feitas
    desde que a transação foi iniciada e, em seguida, imprime uma
    mensagem de erro.
   </p></div>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">try {<br />  </span><span style="color: #0000BB">$dbh </span><span style="color: #007700">= new </span><span style="color: #0000BB">PDO</span><span style="color: #007700">(</span><span style="color: #DD0000">'odbc:SAMPLE'</span><span style="color: #007700">, </span><span style="color: #DD0000">'db2inst1'</span><span style="color: #007700">, </span><span style="color: #DD0000">'ibmdb2'</span><span style="color: #007700">,<br />      array(</span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">ATTR_PERSISTENT </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">true</span><span style="color: #007700">));<br />  echo </span><span style="color: #DD0000">"Connected\n"</span><span style="color: #007700">;<br />} catch (</span><span style="color: #0000BB">Exception $e</span><span style="color: #007700">) {<br />  die(</span><span style="color: #DD0000">"Não foi possível conectar: " </span><span style="color: #007700">. </span><span style="color: #0000BB">$e</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getMessage</span><span style="color: #007700">());<br />}<br /><br />try {<br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setAttribute</span><span style="color: #007700">(</span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">ATTR_ERRMODE</span><span style="color: #007700">, </span><span style="color: #0000BB">PDO</span><span style="color: #007700">::</span><span style="color: #0000BB">ERRMODE_EXCEPTION</span><span style="color: #007700">);<br /><br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">beginTransaction</span><span style="color: #007700">();<br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exec</span><span style="color: #007700">(</span><span style="color: #DD0000">"insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"</span><span style="color: #007700">);<br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">exec</span><span style="color: #007700">(</span><span style="color: #DD0000">"insert into salarychange (id, amount, changedate)<br />      values (23, 50000, NOW())"</span><span style="color: #007700">);<br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">commit</span><span style="color: #007700">();<br /><br />} catch (</span><span style="color: #0000BB">Exception $e</span><span style="color: #007700">) {<br />  </span><span style="color: #0000BB">$dbh</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">rollBack</span><span style="color: #007700">();<br />  echo </span><span style="color: #DD0000">"Falha: " </span><span style="color: #007700">. </span><span style="color: #0000BB">$e</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getMessage</span><span style="color: #007700">();<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  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 essas informações para
  construir mais atualizações e consultas; enquanto a transação estiver ativa, você
  tem a garantia de que ninguém mais pode fazer alterações enquanto você está
  no meio do seu trabalho. Para ler mais sobre transações, consulte a
  documentação fornecida pelo seu servidor de banco de dados.
 </p>
</div>
<?php manual_footer($setup); ?>