2011-02-07 20 views
7

Sto osservando diversi modi di configurare Doctrine 2 per usare connessioni master/slave con MySQL. Il set up dovrebbe essere tale che ci sia un master database con più slave. Tutte le istruzioni SELECT dovrebbero provenire da uno slave live casuale e qualsiasi istruzione UPDATE, INSERT, DELETE sarà sempre delegata alla connessione master.Connessioni Doctrine 2 Master/Slave

Qualcuno ha impostato Doctine 2 in questo modo o ha qualche idea su come affrontarlo?

risposta

0

Per quanto ne so non v'è supporto integrato per questo nella Dottrina 2.

sembra proprio come se (almeno con mysql), questo problema sta per essere risolto in ultima analisi, altrove. Sia in mysql_proxy, o tramite alcuni molto recente lavoro con mysqlnd (il mysql estensione driver nativo per PHP)

Poiché nessuno di questi sono pronti per la prima serata (anche se mysql_proxy potrebbe essere), l'unica opzione immediata è, purtroppo, per iniziare guardando il DBAL di Doctrine ed estendendo le classi integrate per gestire le cose in modo intelligente - significa che potrebbe essere una buona idea rilevare se la richiesta corrente ha effettuato operazioni e quindi forzare le letture successive a utilizzare il master , evitando qualsiasi problema relativo al ritardo di replica.

Speriamo di vedere una soluzione più formale dal team Doctrine nei prossimi 6-12 mesi. Ma se ne hai bisogno ora, è fai-da-te, AFAIK.

+0

Alla fine ho optato per implementare il nostro involucro di connessione che compare avere fatto il trucco Spero che D2 sviluppi ufficialmente la funzionalità in una versione successiva. – Kevin

7

Doctrine2 dispone ora di MasterSlaveConnection nello spazio dei nomi \ Doctrine \ DBAL \ Connections.

EDIT: Non leggere qui di seguito a meno che questo pezzo non funziona

Non ha più bisogno di un overloader, le configurazioni DBAL prenderanno gli schiavi di per sé. per esempio.

connections: 
      default: 
       driver: %database_driver% 
       host:  %database_host% 
       dbname: %database_name% 
       user:  %database_user% 
       password: %database_password% 
       slaves: 
        slave1: 
         host:  %database_slave1% 
         dbname: %database_name% 
         user:  %database_user% 
         password: %database_password% 

Se il non funziona sopra, provare questo

Qualcosa di semplice, basta mettere tubi (|) tra ogni host

default: 
       driver: %database_driver% 
       host:  %database_host%|%database_slave%|%database_slave2% 
       port:  3306 
       dbname: %database_name% 
       user:  %database_user% 
       password: %database_password% 
       wrapper_class: \Foo\Bar\Symfony\Doctrine\Connections\MasterSlave 


<?php 
namespace Foo\Bar\Symfony\Doctrine\Connections; 
use \Doctrine\DBAL\Connections\MasterSlaveConnection; 
use Doctrine\DBAL\Connection, 
     Doctrine\DBAL\Driver, 
     Doctrine\DBAL\Configuration, 
     Doctrine\Common\EventManager, 
     Doctrine\DBAL\Event\ConnectionEventArgs, 
     Doctrine\DBAL\Events, 
     Doctrine\DBAL\Cache\QueryCacheProfile; 

class MasterSlave extends MasterSlaveConnection 
{ 
     public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null) 
     { 
       $tempParams = array(
           'master' => array() 
           , 'slaves' => array() 
           , 'driver' => $params['driver'] 
           ); 
       $hosts = explode('|', $params['host']); 
       unset($params['host']); 
       foreach($hosts as $num => $host) 
       { 
         $params['host'] = $host; 
         if($num == 0) 
         { 
           $tempParams['master'] = $params; 
         } 
         else 
         { 
           $tempParams['slaves'][] = $params; 
         } 
       } 

       if(!isset($tempParams['master']['driver'])) 
         $tempParams['master']['driver'] = "pdo_mysql"; 

       foreach($tempParams['slaves'] as $k => $slave) 
       { 
         if(!isset($slave['driver'])) 
           $tempParams['slaves'][$k]['driver'] = "pdo_mysql"; 
       } 
       parent::__construct($tempParams, $driver, $config, $eventManager); 
     } 

     public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null) 
     { 
       try 
       { 
         return parent::executeQuery($query, $params, $types, $qcp); 
       } 
       catch(\Exception $e) 
       { 
         $logger = new \Uelib\Core\Logger(); 
         $message = $e->getMessage() . "\nSql: " . $query . "\nParams: \n" . print_r($params, true); 
         $logger->log($message); 
         throw $e; 
       } 
     } 
} 
+0

l'unico problema è, non riesco a capire come ottenere symfony per giocare con le configurazioni necessarie – Ascherer

+0

Non ne ho più bisogno !!!!, leggi modifica – Ascherer

+2

Potrebbe essere il momento di accettare questo @Kevin no? – alex88