2012-03-30 14 views
-1

データベース操作に使用するオブジェクトがそれぞれmysqliの2つのクラスに分かれています。複数のmysqliオブジェクトを使用したPHPトランザクション処理

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(...); 
    } 
} 

doSomething()方法は、(SELECTは、UPDATE、...等、DELETE)データベースクエリのため$mysqliObjectを使用しています。私は以下の外部をしたい:

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

...しかし、いずれかが失敗した場合、両方のクエリをロールバックしたい。どうやってやるの?

  • 私は「始点」で新しいmysqliオブジェクトを作成し、「エンドポイント」class Aclass Bのデータベースクエリでそれがコミットまたはロールバックするために使用することはできますか?
  • 外部に作成し、__constructor()のとclass Bに同じ$mysqliObjectを渡して、ロールバックまたはコミット(外部)する必要があります。

pro-conでさらに技術を見たいですか?

答えて

2

データベース接続オブジェクトは、接続が同じデータベースサーバーであっても、データベースとは異なる接続を表します。各接続は完全に独立しているため、一方の接続で開始されたトランザクションは他方の接続では表示されません。

すべてのデータベースアクセスが同じサーバーに対して行われている場合は、1つの接続を作成して、その接続にアクセスする必要のあるものに渡します。その後、トランザクションはアプリケーション全体に適用されます。

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); 

異なるデータベースサーバーと通信する場合は、データベースアクティビティを調整できるオブジェクト内のすべての接続をラップする必要があります。どのデータベース接続に飛行中のトランザクションがあるかを追跡するのは、オブジェクトの責任です。

+0

基本的に私の質問は、別のアプローチを尋ねることを意味しました。たぶん私はちょっとチートして窓からOOPを投げたかったのかもしれません。あなたが言及したように進めます。 – Dyin

+0

これで幸運です。想像上のプログラムではうまくいくかもしれませんが、実際には[コマンドは同期していません](http://dev.mysql.com/doc/refman/5.0/ja/commands-out-of-sync.html) 。問題は明らかにmysqliの使用を述べています。 – doug65536

0

すべてのビジネスロジックに1つのMySQLオブジェクト接続を使用してください...シングルトンパターンを見てください。コンストラクタに渡すことも、静的なクラスメソッドを使ってmysqlオブジェクトを取得することもできます。

最後に、トランザクションを開始する場所は同じです。接続は同じでなければなりません。最善のものは抽象的なもので、一般的なデータベースアクセスレイヤーになります。

+0

シングルトンは使用しないでください。 http://gooh.posterous.com/singletons-in-php – GordonM

+0

ありがとう、面白い記事。だから、提案はデータベースオブジェクトを挿入するだけですか? –

+0

ええ、依存性注射は行く方法です。同じオブジェクトをすべての扶養家族に注入することは、シングルトンと同じ効果があります。後である扶養家族の1人が異なる接続を必要とする場合は、別のデータベースオブジェクトを与えるだけです。 – GordonM