2009-07-05 2 views
12

Ich verwende den folgenden Code für die Transaktion in Zend Framework, aber die Rollback-Funktion funktioniert nicht (Daten werden in die Datenbank von insertSome ($ data) eingefügt). Was ist los?Kann keine Transaktion in Zend Framework zurücksetzen

  $db->beginTransaction(); 
      try{ 
       $model->insertSome($data); 
       $model->insertAll($data2); //this line cannot be run and the whole transaction should be rolled back. 
       $db->commit(); 
      } catch (Exception $e) { 
       $db->rollBack(); 
       echo $e->getMessage(); 
      } 
+7

Ist Ihr DB auf jeden Fall MySQL mit MyISAM-Tabellen? Sie unterstützen keine Transaktionen. Sie müssen InnoDB-Tabellen verwenden, wenn Sie Transaktionsunterstützung wünschen. – nos

+0

Ja, ich verwende MyISAM-Tabellen. Ich habe zu InnoDB-Tabellen gewechselt und es funktioniert. Vielen Dank. – Billy

Antwort

20

Wir können diese Frage nicht aus der Liste der „unbeantwortet“ Fragen auf Stackoverflow bekommen, wenn es mindestens eine Antwort mit einem upvote ist. Also wiederhole ich die Lösung, die Sie oben in den Kommentaren besprochen haben.

@nos schlägt vor:

Ist Ihre DB durch Zufall MySQL MyISAM-Tabellen? Sie unterstützen Transaktionen nicht. Sie müssten InnoDB Tabellen verwenden, wenn Sie die Transaktion unterstützen möchten.

@Billy antwortet:

Ja, ich bin mit MyISAM-Tabellen. Ich habe zu InnoDB-Tabellen gewechselt und es funktioniert. Vielen Dank.

(Ich habe dies als eine Community Wiki Antwort markiert, damit ich keine Punkte von ihm erhalten.)

2

Wenn meine Tabelle InnoDB war, (von SHOW TABLE xxx CREATE gesehen) und meine Transaktion Rollt nicht zurück, was würdest du vorschlagen?

CREATE TABLE `EarningCode` (
`ID` int(11) NOT NULL auto_increment, 
`EarningCode` varchar(16) collate utf8_unicode_ci NOT NULL, 
`Description` varchar(255) collate utf8_unicode_ci NOT NULL, 
`DateEffective` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
`Rate` float NOT NULL, 
PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=1239 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

Es ist ein Teil von Unit-Tests: Ich habe eine Set-up-Methode, die eine transation beginnt:

protected function setUp() 
{ 
    global $db; 

    $db->beginTransaction(); 

    // Insert this tested object into db. 
} 

und eine Träne down-Verfahren, die sicherstellen sollen, dass die Zeile nicht in die db eingefügt wird (jeweils Wenn ein Test in dieser Testklasse ausgeführt wird, führt er das Paar setUp/tearDown aus, und deshalb möchte ich keine Duplikate, die meine db-Tabelle füllen).

protected function tearDown() 
{ 
    global $db; 

    $db->rollBack(); 
} 

Ich habe überprüft, welche SQL ausgeführt wird, und ich kann das autocommit sehen auf false gesetzt ist, wenn die Transaktion gestartet wird, und schaltet auf true nach dem Walzen zurück, aber die Zeile eingefügt bleibt.

0

Ihr Code ist in Ordnung.

Überprüfen Sie Ihre Tabellenoption. Sie benötigen Transactional Engine mit InnoDb

2

Für zukünftige Verwendung, um zu wissen, ob es wirklich eine DB-Ausnahme ist, verwenden Sie stattdessen Zend_Db_Exception.

} catch (Zend_Db_Exception $e) { 
    $db->rollBack(); 
    echo $e->getMessage(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
}