2012-03-30 4 views
-1

Lässt sich der Fall, dass wir zwei separate Klassen haben, jedes besitzt ein mysqli Objekt für Datenbankoperationen verwenden.PHP-Transaktionsverarbeitung mit mehreren mysqli-Objekt

class A{ 
    protected $mysqliObject; 
    public function __constructor(){ 
    $this->mysqliObject=new mysqli(...) 
    } 
    public function doSomething(){ 
    $this->mysqliObject->query(...); 
    } 
} 
class B{ 
    protected $mysqliObject; 
    public function __constructor(){ 
    $this->mysqliObject=new mysqli(...) 
    } 
    public function doSomething(){ 
    $this->mysqliObject->query(...); 
    } 
} 

Die doSomething() Methoden verwenden, um die $mysqliObject für eine Datenbankabfrage (SELECT, UPDATE, DELETE, etc ...). Ich möchte Folgendes außerhalb tun:

// Start point 
$aObject=new A(); 
$bObject=new B(); 
$aObject->doSomething(); 
$bObject->doSomething(); 
// End point 

... aber ich möchte beide Abfragen zurücksetzen, wenn einer von ihnen fehlschlägt. Wie kann ich das machen?

  • Kann ich ein brandneues mysqli Objekt bei „Startpunkt“, und verwenden Sie es auf „Endpunkt“ die Datenbankabfrage von class A und class B zu begehen oder Rollback?
  • Muss ich außerhalb erstellen, und übergeben Sie die gleichen $mysqliObject an die __constructor()class A und class B, und verwenden Sie das Rollback oder Commit (außerhalb).

Möchten mehr Techniken mit Pro-Con's sehen.

Antwort

2

Jedes Datenbankverbindungsobjekt, das Sie haben, stellt eine andere Verbindung zur Datenbank dar, auch wenn die Verbindung zum selben Datenbankserver besteht. Jede Verbindung ist vollständig unabhängig voneinander, sodass eine in einer Verbindung gestartete Transaktion für die andere Verbindung nicht sichtbar ist.

Wenn der gesamte Datenbankzugriff auf denselben Server erfolgt, erstellen Sie einfach eine einzelne Verbindung, und übergeben Sie sie an alles, das Zugriff auf die Verbindung benötigt. Dann wird die Transaktion anwendungsweit durchgeführt.

class ClassThatNeedsDbAccess 
{ 
    protected $connection = NULL; 

    protected function doQuery ($query) 
    { 
     return ($this -> connection -> execute ($query)); 
    } 

    public function __construct (PDO $connection) 
    { 
     $this -> connection = $connection; 
    } 
} 

class OtherClassThatNeedsDbAccess extends ClassThatNeedsDbAccess 
{ 
} 

$myDb = new PDO ('dsn_goes_here'); 

$obj1 = new ClassThatNeedsDbAccess ($myDb); 
$obj2 = new OtherClassThatNeedsDbAccess ($myDb); 

Wenn Sie mit verschiedenen Datenbankservern sprechen, sollten Sie wahrscheinlich alle Verbindungen in ein Objekt umbrechen, das die Datenbankaktivität koordinieren kann. Es liegt in der Verantwortung dieses Objekts zu verfolgen, welche Datenbankverbindung eine Transaktion im Flug hat.

+0

Grundsätzlich wollte meine Frage einen anderen Ansatz als diesen fragen. Vielleicht wollte ich nur ein bisschen schummeln und OOP aus dem Fenster werfen. Ich werde weitermachen, wie du es erwähnt hast. – Dyin

+0

Viel Glück damit. Das könnte in imaginären Programmen funktionieren, aber in der Praxis werden Sie darauf stoßen, dass [Befehle nicht mehr synchron sind] (http://dev.mysql.com/doc/refman/5.0/en/commands-out-of-sync.html) . Die Frage besagt eindeutig die Verwendung von mysqli. – doug65536

0

Verwenden Sie ein MySQL-Objekt - Verbindung für alle Ihre Geschäftslogik ... werfen Sie einen Blick auf Singleton-Muster. Sie können es an den Konstruktor übergeben oder Sie können die statische Klassenmethode verwenden, um das mysql-Objekt zu erhalten.

Dann ist es eine Frage von Ihnen, wo Sie Ende Transaktion starten, Verbindung muss die gleiche sein. Am besten wäre es in eine allgemeine Datenbankzugriffsschicht zu abstrahieren.

+0

Verwenden Sie keine Singletons. http://gooh.posterous.com/singletons-in-php – GordonM

+0

danke, interessanter Artikel. Also Vorschlag ist nur inject Datenbankobjekt in? –

+0

Ja, Abhängigkeitsinjektion ist der Weg zu gehen. Das gleiche Objekt in alle Abhängigen zu injizieren hat die gleiche Wirkung wie ein Singleton, und wenn Sie zu einem späteren Zeitpunkt feststellen, dass einer der Abhängigen eine andere Verbindung benötigt, müssen Sie ihm nur ein anderes Datenbankobjekt geben. – GordonM