<?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 => 'de',
  ),
  'this' => 
  array (
    0 => 'pdo.transactions.php',
    1 => 'Transaktionen und auto-commit',
    2 => 'Transaktionen und auto-commit',
  ),
  'up' => 
  array (
    0 => 'book.pdo.php',
    1 => 'PDO',
  ),
  'prev' => 
  array (
    0 => 'pdo.connections.php',
    1 => 'Verbindungen und Verbindungsmanagement',
  ),
  'next' => 
  array (
    0 => 'pdo.prepared-statements.php',
    1 => 'Prepared Statements und Stored Procedures',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'de',
    '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">Transaktionen und auto-commit</h1>

 <p class="para">
  Jetzt, wo Sie via PDO verbunden sind, müssen Sie sich bewusst machen, wie PDO
  Transaktionen verwaltet, bevor Sie anfangen, Abfragen auszuführen. Falls Sie
  noch nie mit Transaktionen zu tun hatten, diese bieten 4 wichtige Features:
  Atomizität, Konsistenz (Consistency), Isolation und Dauerhaftigkeit
  (Durability) (ACID). Einfach gesagt wird alles in einer Transaktion, auch
  wenn es in Einzelschritten ausgeführt wird, garantiert in sicherer Weise in
  die Datenbank eingetragen, ohne Beeinträchtigung durch andere Verbindungen,
  wenn es abgeschickt wird. Aktivitäten in Transaktionen können auch
  automatisch annulliert werden (wenn Sie es noch nicht abgeschickt haben), was
  Fehlerbehandlung in Ihren Scripts einfacher macht.
 </p>
 <p class="para">
  Transaktionen werden typischerweise implementiert, indem Ihre Menge an
  Änderungen &quot;aufgespart&quot; wird und dann in einem Rutsch abgearbeitet werden.
  Das hat den netten Nebeneffekt, dass die Effizienz der Aktualisierungen
  drastisch erhöht wird. In anderen Worten können Transaktionen Ihre Scripts
  schneller und möglicherweise auch robuster machen. Aber Sie müssen sie
  korrekt verwenden, um davon zu profitieren.
 </p>
 <p class="para">
  Unglücklicherweise unterstützt nicht jede Datenbank Transaktionen, deswegen
  muss PDO in einem &quot;auto-commit&quot; genannten Modus laufen, wenn Sie die
  Verbindung zum ersten Mal öffnen. &quot;Auto-commit&quot; bedeutet, dass jede Abfrage,
  die Sie ausführen ihre eigene implizite Transaktion besitzt, wenn die
  Datenbank das unterstützt, oder keine Transaktion, wenn die Datenbank keine
  Transaktionen unterstützt. Wenn Sie eine Transaktion benötigen, müssen Sie
  eine mit der Methode <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span>
  initiieren. Wenn der zu Grunde liegende Treiber keine Transaktionen
  unterstützt, wird eine <code class="literal">PDOException</code> geworfen (unbeachtet
  Ihrer Einstellungen zur Fehlerbehandlung: dies ist immer eine ernste
  Fehlerbedingung). Wenn Sie dann in einer Transaktion sind, können Sie
  <span class="methodname"><a href="pdo.commit.php" class="methodname">PDO::commit()</a></span> oder
  <span class="methodname"><a href="pdo.rollback.php" class="methodname">PDO::rollBack()</a></span> benutzen, um die Transaktion
  abzuschließen, abhängig vom Erfolg des Codes, den Sie während der Transaktion
  ausgeführt haben.
 </p>
 <div class="warning"><strong class="warning">Warnung</strong>
  <p class="para">
   PDO überprüft nur auf Treiberebene auf Transaktionsfähigkeit. Wenn bestimmte
   Laufzeitbedingunen ergeben, dass Transaktionen nicht verfügbar sind, wird
   <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> trotzdem ohne Fehler <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>
   zurückgeben, wenn der Server die Anfrage zum Start einer Transaktion
   akzeptiert.
  </p>
  <p class="para">
   Ein Beispiel wäre es, Transaktionen auf MyISAM-Tabellen in einer
   MySQL-Datenbank zu verwenden
  </p>
 </div>
 <div class="warning"><strong class="warning">Warnung</strong>
  <p class="para">
   <em>Implicit Commits with DDL Statements:</em>
   Some databases automatically issue an implicit <code class="literal">COMMIT</code>
   when a database definition language (DDL) statement, such as <code class="literal">DROP
   TABLE</code> or <code class="literal">CREATE TABLE</code>, is executed within a
   transaction. This means that any prior changes made within the same
   transaction will be <em>automatically committed</em> and cannot
   be rolled back.
  </p>
  <p class="para">
   <code class="literal">MySQL</code> and <code class="literal">Oracle</code> are example databases
   that exhibit this behavior.
  </p>
 </div>
 <p class="para">
  <div class="example" id="example-1">
   <p><strong>Beispiel #1 Implicit Commit Example</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">// Implicit COMMIT occurs here<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">// This will NOT undo the INSERT/CREATE for MySQL or Oracle<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  <em>Best Practice:</em> Avoid executing DDL statements inside
  transactions if using databases that enforce this behavior. If necessary,
  separate DDL operations from transactional logic.
 </p>
 <p class="para">
  Wenn das Script endet oder die Verbindung im Begriff ist, geschlossen zu
  werden und Sie eine Transaktion ausstehen haben, wird PDO automatisch einen
  Rollback durchführen. Dies ist eine Sicherheitsmaßnahme, um Inkonsistenzen in
  dem Fall, dass das Script unerwartet beendet wird, zu vermeiden - wenn Sie
  die Transaktion nicht explizit ausgeführt haben, wird angenommen, dass etwas
  schiefgegangen ist, deswegen wird zur Sicherheit Ihrer Daten ein Rollback
  durchgeführt.
 </p>
 <div class="warning"><strong class="warning">Warnung</strong>
  <p class="para">
   Der automatische Rollback wird nur durchgeführt, wenn Sie die Transaktion
   per <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> starten. Wenn Sie manuell
   eine Abfrage ausführen, die eine Transaktion startet, kann PDO nichts davon
   wissen und kann deswegen auch keinen Rollback durchführen, wenn etwas
   schiefgeht.
  </p>
 </div>
 <p class="para">
  <div class="example" id="example-2"><p><strong>Beispiel #2 Mehrere Abfragen in einer Transaktion</strong></p>
   <div class="example-contents"><p>
    Im folgenden Beispiel nehmen wir an, dass wir einen Satz von Einträgen für
    einen neuen Angestellten eintragen wollen, dem die ID-Nummer 23 zugeordnet
    wurde. Zusätzlich zur Angabe der Basisdaten für diese Person müssen wir
    auch ihr Gehalt festhalten. Es ist ziemlich einfach, zwei getrennte
    Aktualisierungen durchzuführen, aber indem wir sie in
    <span class="methodname"><a href="pdo.begintransaction.php" class="methodname">PDO::beginTransaction()</a></span> und
    <span class="methodname"><a href="pdo.commit.php" class="methodname">PDO::commit()</a></span> einschließen, garantieren wir, dass
    niemand anderes diese Änderungen sieht, bis sie komplett sind. Wenn etwas
    schiefgeht, wird der <code class="literal">catch</code>-Block alle seit Beginn der
    Transaktion durchgeführten Änderungen rückgängig machen und dann eine
    Fehlermeldung ausgeben.
   </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">"Unable to connect: " </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">"Failed: " </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">
  Sie sind nicht darauf beschränkt, Änderungen in einer Transaktion
  durchzuführen. Sie können auch komplexe Abfragen ausführen um Daten zu
  erhalten, und diese Informationen etwa dazu benutzen, mehr Änderungen und
  Abfragen zu erzeugen. Während die Transaktion aktiv ist, kann garantiert
  niemand anderes Änderungen durchführen, während Sie bei der Arbeit sind. Um
  ehrlich zu sein, stimmt das nicht 100%, aber es ist für den Anfang
  ausreichend, falls Sie noch nie von Transaktionen gehört haben.
 </p>
</div>
<?php manual_footer($setup); ?>