2009-12-01 12 views
7

Estoy escribiendo una aplicación que requiere que el interruptor Maestro/Esclavo ocurra dentro de la capa de aplicación. Como es ahora, instanciando un objeto Zend_Db_Table en la creación del asignador, y luego establezco Default Adapter al esclavo.Interruptor Maestro/Esclavo en la capa de aplicación de Zend Framework

Ahora dentro de la classe asignador de base, que tienen el siguiente método:

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

que necesitan una comprobación de validez en esto. No creo que la sobrecarga sea demasiado, solo sospecho que debe haber una mejor manera.

Respuesta

3

Un objeto del tipo Zend_Db_Table_Row_Abstract recuerda qué objeto de la tabla lo produjo. Pero puede cambiar la tabla asociada antes de llamar al 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

¿Qué tal algo así como una clase base que extiendes y que realiza la puesta en marcha?

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

Todavía necesitaría poder cambiar el adaptador DB sobre la marcha, así que no estoy seguro de si esto funcionaría. – Pro777

0

Aunque lo más probable es que ya se le ocurrió una solución todavía a publicar la forma en que lo hice: que estaba buscando una solución para el mismo problema y se le ocurrió la idea de poner la lógica para eso en el adaptador.

Extendí el Zend_Db_Adapter_Abstract y agregué el atributo booleano $ write. Añadí métodos públicos getter y setter para eso también.

Mi adaptador guarda dos configuraciones de base de datos/conexiones diferentes: una para el maestro (para escritura) y otra para el esclavo (para lectura). (En realidad no es una configuración sino muchas así que tengo una especie de conjunto de masters y bálsamos que se seleccionan al azar por peso.)

Ahora hago lo siguiente: Antes de ejecutar una consulta, $ write debe establecerse en true o falso. En el método connect(), el adaptador se conecta o usa la conexión correcta según el valor de $ write.