Ich stimme nicht mit Bill Karwins Einschätzung überein, dass es verrückt ist, die begonnenen Transaktionen zu verfolgen, obwohl ich dieses Wort mag.
Ich habe eine Situation, in der ich Ereignisbehandlungsfunktionen habe, die von einem nicht von mir geschriebenen Modul aufgerufen werden könnten. Meine Event-Handler erstellen eine Menge von Datensätzen in der Datenbank. Ich muss auf jeden Fall einen Rollback durchführen, wenn etwas nicht korrekt übergeben wurde oder fehlt oder wenn etwas schief läuft. Ich kann nicht wissen, ob der Code des externen Moduls, der den Event-Handler auslöst, DB-Transaktionen verarbeitet, da der Code von anderen Leuten geschrieben wurde. Ich habe keine Möglichkeit gefunden, die Datenbank abzufragen, um zu sehen, ob eine Transaktion im Gange ist.
Ich zähle also mit. Ich verwende CodeIgniter, die seltsame Dinge zu tun scheint, wenn ich es bitten, mit verschachtelten db-Transaktionen (z.B. Aufruf es trans_start() Methode mehr als einmal) zu starten. Mit anderen Worten, ich kann nicht einfach trans_start() in meinen Event-Handler einfügen, denn wenn eine externe Funktion ebenfalls trans_start() verwendet, werden Rollbacks und Commits nicht korrekt ausgeführt. Es besteht immer die Möglichkeit, dass ich noch nicht herausgefunden habe, wie ich diese Funktionen richtig verwalte, aber ich habe viele Tests durchgeführt.
Alles, was meine Event-Handler wissen müssen, ist, ob eine DB-Transaktion bereits von einem anderen Modul initiiert wurde, das sie aufruft. Wenn ja, wird keine weitere neue Transaktion gestartet und auch keine Rollbacks oder Commits berücksichtigt. Es vertraut darauf, dass wenn eine externe Funktion eine DB-Transaktion initiiert hat, dann wird es auch Rollbacks/Commits behandeln.
Ich habe Wrapper-Funktionen für CodeIgniter's Transaktionsmethoden und diese Funktionen inkrementieren/dekrementieren einen Zähler.
function transBegin(){
//increment our number of levels
$this->_transBegin += 1;
//if we are only one level deep, we can create transaction
if($this->_transBegin ==1) {
$this->db->trans_begin();
}
}
function transCommit(){
if($this->_transBegin == 1) {
//if we are only one level deep, we can commit transaction
$this->db->trans_commit();
}
//decrement our number of levels
$this->_transBegin -= 1;
}
function transRollback(){
if($this->_transBegin == 1) {
//if we are only one level deep, we can roll back transaction
$this->db->trans_rollback();
}
//decrement our number of levels
$this->_transBegin -= 1;
}
In meiner Situation ist dies die einzige Möglichkeit, nach einer bestehenden Datenbank-Transaktion zu suchen. Und es funktioniert. Ich würde nicht sagen, dass "die Anwendung DB-Transaktionen verwaltet". Das ist in dieser Situation wirklich unwahr. Es wird lediglich geprüft, ob ein anderer Teil der Anwendung eine DB-Transaktion gestartet hat, um die Erstellung verschachtelter DB-Transaktionen zu vermeiden.