2012-07-09 14 views
6

Tengo dos conexiones de base de datos, una que se utiliza para la mayoría de mis datos de aplicación y otra que solo se usa para lecturas.Yii restringe la conexión de la base de datos a solo lectura

Aunque puedo configurar mi cuenta de usuario de base de datos para que solo permita lecturas, hay otras personas administrando este sistema, y ​​quiero cierta redundancia a nivel de aplicación para evitar por completo las escrituras involuntarias utilizando las clases ActiveRecord estándar de Yii.

Encontré este bit de información en los foros, pero me preguntaba si alguien podría confirmar que este es un buen enfoque y/o sugerir otro.

public function onBeforeSave($event) 
{ 
    $this->db = Yii::app()->masterDb; 
} 

public function onAfterSave($event) 
{ 
    $this->db = Yii::app()->db; 
} 

http://www.yiiframework.com/forum/index.php/topic/5712-active-record-save-to-different-server-load-balancefail-over-setup/

+2

El uso de un usuario de base de datos independiente es la mejor manera de hacerlo. –

+1

@ tereško ... y la única manera de garantizar plenamente que ningún código futuro rompa esta "convención" ... – Ron

+0

Estoy de acuerdo en que un solo DB de datos es la solución más elegante, sin embargo quiero redundancia ya que no confío en las personas administrando el sistema 100% –

Respuesta

4

por ese enlace que ha proporcionado a los foros de Yii, hay una extensión que se encarga de esto para usted: http://www.yiiframework.com/extension/dbreadwritesplitting

probablemente me miro a los que en primer lugar, si usted tiene tiene muchos modelos AR. Puede ir a la ruta de Comportamiento (como se sugiere en la publicación del foro) como otra opción.

Pero hagas lo que hagas, querrás anular antes de Guardar/posponer en lugar de onFeforeSave/onAfterSave. Esos métodos son para desencadenar eventos, no solo para ejecutar su propio código especial. Y, por another one of the forum posts, deberá establecer su variable AR db utilizando una llamada estática. Así código de Sergey debería ser en realidad:

class MyActiveRecord extends CActiveRecord 
{ 
    ... 
    public function beforeSave() 
    { 
     // set write DB 
     self::$db = Yii::app()->masterDb; 

     return parent::beforeSave(); 
    } 

    public function afterSave() 
    { 
     // set read db 
     self::$db = Yii::app()->db; 

     return parent::beforeSave(); 
    } 
    ... 
} 


class User extends MyActiveRecord {} 
class Post extends MyActiveRecord {} 
... 
+0

Esa extensión es bastante ingeniosa, tendré que leer un poco más al respecto. –

2
class MyActiveRecord extends CActiveRecord 
{ 
... 
public function onBeforeSave($event) 
{ 
    // set write DB 
    $this->db = Yii::app()->masterDb; 
} 

public function onAfterSave($event) 
{ 
    // set read db 
    $this->db = Yii::app()->db; 
} 
... 
} 


class User extends MyActiveRecord {} 
class Post extends MyActiveRecord {} 
... 

U tiene que tratar de esa manera :) Pero en mi humilde opinión no es lo suficientemente bueno. Creo que va a haber algunos errores o defectos

+0

Gracias por incluir las partes de esta solución que dejé fuera de mi publicación, para futuras referencias de cualquier persona que vea esta pregunta. ¿A qué tipo de errores/defectos se refiere? –

+0

@JohnZ, acorncom dice: 'onBeforeSave/onAfterSave. Esos métodos son para desencadenar eventos, no solo para ejecutar su propio código especial. Es lo que quiero decir. – Sergey

2

Dado un escenario en el que el esclavo no puede actualizar con el maestro, usted podría encontrarse con problemas. Porque después de actualizar los datos, es posible que lea de una versión anterior.

Mientras que los enfoques dados en el foro son muy limpios y escritos por autores que son en su mayoría Yii magos. También tengo una alternativa. Es posible reemplazar el método getDbConnection() en la AR como

public function getDbConnection(){ 
    if (Yii::app()->user->hasEditedData()) { # you've got to write something like this(!) 
    return Yii::app()->masterDb; 
    } else { 
    return Yii::app()->db; 
    } 
} 

, pero todavía tiene que tener cuidado al cambiar las conexiones de bases de datos.

Cuestiones relacionadas