2011-02-07 2 views
7

Я ищу различные способы настройки Doctrine 2 для использования соединений master/slave usng MySQL. Настройка была бы такой, чтобы была одна основная база данных с несколькими подчиненными устройствами. Все операторы SELECT должны поступать из произвольного подчиненного подчиненного устройства, и любые инструкции UPDATE, INSERT, DELETE всегда будут делегированы главному соединению.Doctrine 2 Подключение ведущего/ведомого

Кто-нибудь создал Doctine 2 таким образом или есть идеи о том, как подойти к нему?

ответ

0

Насколько я знаю, не встроенная поддержка для этого в доктрине 2.

Это действительно кажется, что (по крайней мере, с MySQL), эта проблема будет решена в конечном счете, в другом месте. Либо в mysql_proxy, или через какой-то очень недавней работе с mysqlnd (MySQL в нативной расширение драйвера для PHP)

Поскольку ни один из тех, кто готов к прайм (хотя mysql_proxy может быть), ваш единственный непосредственный вариант, к сожалению, чтобы начать глядя на Doalrine DBAL и расширяя встроенные классы, чтобы обрабатывать вещи с умом - это означает, что может быть хорошей идеей определить, выполнил ли текущий запрос какие-либо операции , записывая операции, а затем заставлять любые последующие чтения использовать мастер , избегая любых проблем, связанных с задержкой репликации.

Надеюсь, мы увидим более формальное решение от команды Doctrine в течение следующих 6-12 месяцев. Но если вам это нужно сейчас, это DIY, AFAIK.

+0

В конце концов я решил реализовать свою собственную оболочку Connection, которая появляется чтобы сделать трюк. Надеюсь, D2 официально разработает эту функцию в более позднем выпуске. – Kevin

7

У Doctrine2 теперь есть MasterSlaveConnection в пространстве имен \ Doctrine \ DBAL \ Connections.

EDIT: Dont прочитать ниже, если этот кусок не работает

Dont не нужен overloader больше, то DBAL конфига будет принимать раб самого по себе. например

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% 

Если выше не работает, попробуйте этот

что-то простое, просто положить трубы (|) между каждым хостом

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

проблема только в том, что я не могу понять, как получить симфонию, чтобы играть хорошо с требованиями configs – Ascherer

+0

Dont need this больше !!!!, read edit – Ascherer

+2

Может ли время принять это @Kevin, не так ли? – alex88