Start · Sprachen · PHP · Referenz · oci_rollback

oci_rollback

Funktion

Macht alle ausstehenden, nicht bestätigten Änderungen der aktuellen Oracle-Datenbanktransaktion rückgängig.

seit PHP 5.0.0 Kategorie: db

Signatur

oci_rollback(resource $connection): bool

Beschreibung

oci_rollback() verwirft alle noch nicht mit oci_commit() bestätigten DML-Operationen (INSERT, UPDATE, DELETE) der laufenden Transaktion auf der angegebenen Oracle-Verbindung. Die Funktion beendet gleichzeitig die aktuelle Transaktion, sodass anschließende Datenbankänderungen eine neue Transaktion starten.

In Oracle wird standardmäßig kein Auto-Commit verwendet, wenn Anweisungen über OCI8 ausgeführt werden. Alle Änderungen bleiben so lange temporär, bis sie entweder explizit mit oci_commit() bestätigt oder mit oci_rollback() verworfen werden. Das ermöglicht atomare Operationen und die Umsetzung des ACID-Prinzips.

oci_rollback() wird typischerweise im Fehlerfall eingesetzt, etwa innerhalb eines catch-Blocks, um eine bereits begonnene, aber fehlgeschlagene Transaktion sauber zurückzusetzen. So bleibt die Datenbank in einem konsistenten Zustand.

Zu beachten ist, dass DDL-Anweisungen wie CREATE oder DROP in Oracle einen impliziten Commit auslösen und deshalb nicht durch oci_rollback() rückgängig gemacht werden können.

Parameter

Name Typ Default Beschreibung
$connection Pflicht resource Eine gültige OCI8-Verbindungsressource, die zuvor mit oci_connect(), oci_pconnect() oder oci_new_connect() erzeugt wurde.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn der Rollback erfolgreich war, andernfalls false. Im Fehlerfall kann oci_error() für weitere Diagnoseinformationen verwendet werden.

Beispiele

Einfacher Rollback nach fehlgeschlagener Transaktion

<?php
$conn = oci_connect('benutzer', 'passwort', 'localhost/XE');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlspecialchars($e['message']), E_USER_ERROR);
}

$stid = oci_parse($conn, "INSERT INTO bestellungen (id, artikel) VALUES (1, 'Laptop')");

if (!oci_execute($stid, OCI_NO_AUTO_COMMIT)) {
    $e = oci_error($stid);
    echo 'Fehler: ' . htmlspecialchars($e['message']) . PHP_EOL;
    oci_rollback($conn); // Änderungen verwerfen
    echo 'Transaktion wurde zurückgerollt.' . PHP_EOL;
} else {
    oci_commit($conn); // Änderungen bestätigen
    echo 'Transaktion erfolgreich bestätigt.' . PHP_EOL;
}

oci_free_statement($stid);
oci_close($conn);
Transaktion erfolgreich bestätigt.

Rollback bei mehrstufiger Transaktion mit Fehlerbehandlung

<?php
$conn = oci_connect('benutzer', 'passwort', 'localhost/XE');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlspecialchars($e['message']), E_USER_ERROR);
}

try {
    $stid1 = oci_parse($conn, "UPDATE konten SET saldo = saldo - 500 WHERE konto_id = 1");
    $stid2 = oci_parse($conn, "UPDATE konten SET saldo = saldo + 500 WHERE konto_id = 2");

    if (!oci_execute($stid1, OCI_NO_AUTO_COMMIT)) {
        throw new RuntimeException('Fehler bei Abbuchung');
    }
    if (!oci_execute($stid2, OCI_NO_AUTO_COMMIT)) {
        throw new RuntimeException('Fehler bei Gutschrift');
    }

    oci_commit($conn);
    echo 'Überweisung erfolgreich durchgeführt.' . PHP_EOL;

} catch (RuntimeException $e) {
    oci_rollback($conn); // Beide Updates verwerfen
    echo 'Fehler: ' . $e->getMessage() . ' — Rollback durchgeführt.' . PHP_EOL;
} finally {
    oci_free_statement($stid1);
    oci_free_statement($stid2);
    oci_close($conn);
}
Überweisung erfolgreich durchgeführt.

// Wichtig · Fallstricke

DDL-Anweisungen: Oracle führt bei DDL-Befehlen (z. B. CREATE TABLE, DROP TABLE, ALTER TABLE) automatisch einen impliziten Commit durch. Solche Operationen können daher nicht mit oci_rollback() rückgängig gemacht werden.

OCI_NO_AUTO_COMMIT: Um manuelle Transaktionskontrolle zu nutzen, muss oci_execute() mit dem Flag OCI_NO_AUTO_COMMIT (früher OCI_DEFAULT) aufgerufen werden. Ohne dieses Flag wird nach jeder Anweisung automatisch ein Commit ausgelöst, und ein nachträglicher Rollback hat keine Wirkung mehr.

Persistente Verbindungen: Bei der Verwendung von oci_pconnect() sollte besonders darauf geachtet werden, dass offene Transaktionen am Ende der Anfrage explizit abgeschlossen werden, da persistente Verbindungen über mehrere Anfragen hinweg wiederverwendet werden und vergessene Transaktionszustände zu schwer nachvollziehbaren Fehlern führen können.