Страница 1 из 1
[РЕШЕНО] Использую 2 компонента DBConnection
Добавлено: 2012.09.26, 18:41
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;
}
Заранее благодарен!
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 11:59
samdark
Лучше два компонента сделать.
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:04
DropSQL
Это же 2 компонента, не так ли? или я чего-то не так понимаю?
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:05
anton44eg
да. потом в модели можно переопределить метод getDbConnection() и модели будут к нужной БД идти, ну а для DAO Yii::app()->slave->createCommand() и Yii::app()->db->createCommand()
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:11
DropSQL
Вы не поняли фишку, мне нужно чтобы все селекты шли на slave, а инсерты и апдейты, делеты на master.
Я сначала сделал onBeforeFind - и тупо менял БД, мне эта идея до сих пор нравится, но конструкция
не работает в таком случае, потому что cache отрабатывает раньше чем onBeforeFind
Пришлось сделать такой вид:
Код: Выделить всё
Model::master()->cache(1)->findAll();
Model::slave()->cache(1)->findAll();
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:13
DropSQL
Если Знаете как решить подскажите плз (аналог onBeforeFind, чтобы автоматом определяло), буду очень благодарен.
И вопрос стоял в том как узнать с какого компонента идет запрос в профилировании?
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:40
samdark
А зачем что-то менять, если используется кеш?
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 12:53
DropSQL
хорошо, ты прав
тогда возникает вопрос
а как можно узнать использую я кэширование или нет?
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 13:19
samdark
$this->dbConnection->queryCachingCount>0
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 13:35
Denyii
DropSQL писал(а):Вы не поняли фишку, мне нужно чтобы все селекты шли на slave, а инсерты и апдейты, делеты на master......
Не давно на форуме видел ссылку на это расширение
http://www.yiiframework.com/extension/d ... splitting/
Тут:
viewtopic.php?f=3&t=8533 (Master - slave репликация + Yii)
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 14:22
DropSQL
супер решение!
спасибо большое, сейчас только проверю как оно работает с кэшированием, по коду проблема должна остаться
Re: Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 14:48
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;
}
Re: [РЕШЕНО] Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 14:59
DropSQL
Проверил, работает кеширование хорошо.
Re: [РЕШЕНО] Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 15:55
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 {
Re: [РЕШЕНО] Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 15:59
lancecoder
1 ар+дао(если в нужном месте)
2 ар
Re: [РЕШЕНО] Использую 2 компонента DBConnection
Добавлено: 2012.09.27, 17:44
DropSQL
прегматч можно заменить на сторковую функцию вроде strpos, если это так критично.
Работает прекрасно включая кеширования.
Если бы вы читали выше - поняли бы почему этот костыль меня не устроил, там проблемы как минимум с кэшированием.
Меня реализация этого модуля очень порадовала, я уверен что больших тормозов эта строковая функция не создаст, относительно остальных тормозов фреймворка.