[РЕШЕНО] Использую 2 компонента DBConnection

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

[РЕШЕНО] Использую 2 компонента DBConnection

Сообщение DropSQL »

Здравствуйте, подскажите плз, можно ли как-то в профайлинге узнать какой конкретно компонент использовался при выполнении запроса?

Сделал таким путем, возможно не правильно, подскажите как исправить:

Код: Выделить всё

public static function master()
    {
        self::setDbConnection(Yii::app()->db);
        return self::model();
    }

    public static function slave()
    {
        self::setDbConnection(Yii::app()->slave);
        $model = self::model();
        return $model;
    }

    public static function setDbConnection($dbConnection)
    {
        self::$_db = $dbConnection;
    }

    public function getDbConnection()
    {
        if(self::$_db === null){
            $db = parent::getDbConnection();
        }else{
            $db = self::$_db;
        }
        return $db;
    }
Заранее благодарен!
Последний раз редактировалось DropSQL 2012.09.27, 14:51, всего редактировалось 2 раза.

Аватара пользователя
samdark
Администратор
Сообщения: 9296
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Использую 2 компонента DBConnection

Сообщение samdark »

Лучше два компонента сделать.

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

Код: Выделить всё

Yii::app()->slave
Yii::app()->db
Это же 2 компонента, не так ли? или я чего-то не так понимаю?

Аватара пользователя
anton44eg
Сообщения: 2716
Зарегистрирован: 2012.01.25, 13:37
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение anton44eg »

да. потом в модели можно переопределить метод getDbConnection() и модели будут к нужной БД идти, ну а для DAO Yii::app()->slave->createCommand() и Yii::app()->db->createCommand()

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

Вы не поняли фишку, мне нужно чтобы все селекты шли на slave, а инсерты и апдейты, делеты на master.
Я сначала сделал onBeforeFind - и тупо менял БД, мне эта идея до сих пор нравится, но конструкция

Код: Выделить всё

Model::model()->cache(1)->findAll();
не работает в таком случае, потому что cache отрабатывает раньше чем onBeforeFind :( Пришлось сделать такой вид:

Код: Выделить всё

Model::master()->cache(1)->findAll();
Model::slave()->cache(1)->findAll();

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

Если Знаете как решить подскажите плз (аналог onBeforeFind, чтобы автоматом определяло), буду очень благодарен.
И вопрос стоял в том как узнать с какого компонента идет запрос в профилировании?

Аватара пользователя
samdark
Администратор
Сообщения: 9296
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Использую 2 компонента DBConnection

Сообщение samdark »

А зачем что-то менять, если используется кеш?

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

хорошо, ты прав :) тогда возникает вопрос :) а как можно узнать использую я кэширование или нет?

Аватара пользователя
samdark
Администратор
Сообщения: 9296
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Использую 2 компонента DBConnection

Сообщение samdark »

$this->dbConnection->queryCachingCount>0

Denyii
Сообщения: 147
Зарегистрирован: 2012.02.13, 14:55

Re: Использую 2 компонента DBConnection

Сообщение Denyii »

DropSQL писал(а):Вы не поняли фишку, мне нужно чтобы все селекты шли на slave, а инсерты и апдейты, делеты на master......
Не давно на форуме видел ссылку на это расширение http://www.yiiframework.com/extension/d ... splitting/
Тут:viewtopic.php?f=3&t=8533 (Master - slave репликация + Yii)

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

супер решение! :) спасибо большое, сейчас только проверю как оно работает с кэшированием, по коду проблема должна остаться

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: Использую 2 компонента DBConnection

Сообщение DropSQL »

решил вроде:

Код: Выделить всё

    public function getSlave() {
        if (!isset($this->_slave)) {
            foreach ($this->slaves as $slaveConfig) {
                if (!isset($slaveConfig['class']))
                    $slaveConfig['class']='CDbConnection';
                try {
                    if ($slave=Yii::createComponent($slaveConfig)) {
                        Yii::app()->setComponent('dbslave',$slave);
                        $this->_slave=$slave;
                        break;
                    }
                } catch (Exception $e) {
                    Yii::log('Create slave database connection failed!','warn');
                    continue;
                }
            }
            if (!$this->_slave) {
                $this->_slave=clone $this;
                $this->_slave->enableSlave=false;
            }
        }
        return $this->_slave;
    }
этот метод заменить на:

Код: Выделить всё

    public function getSlave() {
        if (!isset($this->_slave)) {
            shuffle($this->slaves);
            foreach ($this->slaves as $slaveConfig) {
                if (!isset($slaveConfig['class']))
                    $slaveConfig['class']='CDbConnection';
                try {
                    if ($slave=Yii::createComponent($slaveConfig)) {
                        Yii::app()->setComponent('dbslave',$slave);
                        $this->_slave=$slave;
                        break;
                    }
                } catch (Exception $e) {
                    Yii::log('Create slave database connection failed!','warn');
                    continue;
                }
            }
            if (!$this->_slave) {
                $this->_slave=clone $this;
                $this->_slave->enableSlave=false;
            }
        }
        $this->_slave->cache($this->queryCachingDuration, $this->queryCachingDependency, $this->queryCachingCount);
        $this->cache(0);
        return $this->_slave;
    }

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: [РЕШЕНО] Использую 2 компонента DBConnection

Сообщение DropSQL »

Проверил, работает кеширование хорошо.

grigori
Сообщения: 8
Зарегистрирован: 2012.04.04, 15:19

Re: [РЕШЕНО] Использую 2 компонента DBConnection

Сообщение grigori »

к сожалению, расширение dbreadwritesplitting имеет 2 недостатка:

Код: Выделить всё

self::isReadOperation($sql)
...
 public function isReadOperation($sql) {
   return preg_match('/^\s*(SELECT|SHOW|DESCRIBE|PRAGMA)/i',$sql);
 
1. статический метод должен быть статическим, иначе будут сообщения об ошибке
2. прогонять каждый запрос к базе через preg_match - неэффективно

в общем, это решение на коленке, лучше уж костыль

Код: Выделить всё

class SotmActiveRecord extends  CActiveRecord
{
    private $writeDb;
    private $readDb;
    /**
     * Set the replication switch to use master
     * @return bool
     */
    public function beforeSave()
    {
        self::$db = $this ->writeDb ?: ($this->writeDb = Yii::app()->writeDb);
        return parent::beforeSave();
    }

    /**
     * Set to db to  slave
     * @retur bool
     */
    public function afterSave()
    {
        self::$db = $this ->readDb ?: ($this->readDb = Yii::app()->getDb());
        return parent::afterSave();
    }

    /**
     * Set to db to master
     * @retur bool
     */
    public function beforeDelete()
    {
        self::$db = $this ->writeDb ?: ($this->writeDb = Yii::app()->writeDb);
        return parent::beforeDelete();
    }

    /**
     * Set to db to slave
     * @retur bool
     */
    public function afterDelete()
    {
        self::$db = $this ->readDb ?: ($this->readDb = Yii::app()->getDb());
        return parent::afterDelete();
    }
}
...
class Customers extends SotmActiveRecord {
 

Аватара пользователя
lancecoder
Сообщения: 2532
Зарегистрирован: 2012.06.26, 17:16

Re: [РЕШЕНО] Использую 2 компонента DBConnection

Сообщение lancecoder »

1 ар+дао(если в нужном месте)
2 ар

DropSQL
Сообщения: 102
Зарегистрирован: 2010.02.19, 22:20
Откуда: Киев

Re: [РЕШЕНО] Использую 2 компонента DBConnection

Сообщение DropSQL »

прегматч можно заменить на сторковую функцию вроде strpos, если это так критично.
Работает прекрасно включая кеширования.
Если бы вы читали выше - поняли бы почему этот костыль меня не устроил, там проблемы как минимум с кэшированием.

Меня реализация этого модуля очень порадовала, я уверен что больших тормозов эта строковая функция не создаст, относительно остальных тормозов фреймворка.

Ответить