2009-12-01 12 views
7

J'écris une application qui nécessite que le commutateur Maître/Esclave se produise dans la couche d'application. Comme c'est le cas maintenant, j'instancie un objet Zend_Db_Table à la création du mappeur, puis setDefaultAdapter à l'esclave.Commutateur Maître/Esclave dans la couche d'application Zend Framework

maintenant à l'intérieur de la base mappeur classe, j'ai la méthode suivante:

public function useWriteAdapter() 
{ 
    if(Zend_Db_Table_Abstract::getDefaultAdapter() != $this->_writeDb) 
    { 
     Zend_Db_Table_Abstract::setDefaultAdapter($this->_writeDb); 
     $this->_tableGateway = new Zend_Db_Table($this->_tableName); 
    } 
} 

je besoin d'un test de cohérence à ce sujet. Je ne pense pas que les frais généraux sont trop élevés, je soupçonne juste qu'il doit y avoir un meilleur moyen.

Répondre

3

Un objet de type Zend_Db_Table_Row_Abstract se souvient quel objet de table a produit. Mais vous pouvez modifier le tableau associé avant d'appeler save().

$readDb = Zend_Db::factory(...); // slave 
$writeDb = Zend_Db::factory(...); // master 
Zend_Db_Table::setDefaultAdapter($readDb); 

$myReadTable = new MyTable(); // use default adapter 
$myWriteTable = new MyTable($writeDb); 

$row = $myTable->find(1234)->current(); 

$row->column1 = 'value'; 

$row->setTable($myWriteTable); 

$row->save(); 
1

Que diriez-vous de quelque chose comme une classe de base que vous étendez qui effectue le démarrage?

class My_Db_Table extends Zend_Db_Table 
{ 
    function init() 
    { 
     if (....) { 
      // set the default adaptor to the write-DB-master 
     } 
     parent::init(); 
    } 
} 
// all your models then extend My_Db_Table instead of Zend_Db_Table 
+0

Je devrais toujours être capable de changer l'adaptateur de DB à la volée, donc je ne suis pas sûr que cela fonctionnerait. – Pro777

0

Bien que vous très probablement déjà venu avec une solution que je vais encore poster la façon dont je l'ai fait: Je cherchais un solution pour le même problème et est venu avec l'idée de mettre la logique pour cela dans l'adaptateur.

J'ai étendu le Zend_Db_Adapter_Abstract et ajouté l'attribut booléen $ write. J'ai ajouté des méthodes getter et setter publiques pour cela aussi bien. Mon adaptateur enregistre deux configurations/connexions de base de données différentes: une pour le maître (pour l'écriture) et une pour l'esclave (pour la lecture). (En fait ce n'est pas une configuration mais plusieurs donc j'ai une sorte de pool de maîtres et de pommades qui sont sélectionnés au hasard en fonction du poids.)

Maintenant, je fais ce qui suit: Avant d'exécuter une requête, $ write doit être true ou faux. Dans la méthode connect(), l'adaptateur se connecte ou utilise la bonne connexion en fonction de la valeur de $ write.