6

我有两个数据库连接,一个用于我的大部分应用程序数据,一个仅用于读取。

虽然我可以将我的数据库用户帐户设置为只允许读取,但还有其他人在管理这个系统,我希望在应用程序级别有一些冗余,以绝对防止使用 Yii 的标准 ActiveRecord 类进行意外写入。

在论坛上找到了一些信息,但想知道是否有人可以确认这是一种好方法和/或建议另一种方法。

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/

4

3 回答 3

4

根据您提供给 Yii 论坛的链接,有一个扩展程序可以为您处理这个问题: http ://www.yiiframework.com/extension/dbreadwritesplitting

如果你有很多 AR 模型,我可能会先研究一下。您可以选择行为路线(如该论坛帖子中所建议的那样)作为另一种选择。

但无论你做什么,你都会想要覆盖 beforeSave / afterSave 而不是 onBeforeSave / onAfterSave。这些方法用于触发事件,而不仅仅是运行您自己的特殊代码。而且,根据另一个论坛帖子,您需要使用静态调用设置您的 AR db 变量。所以 Sergey 的代码实际上应该是:

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 {}
...
于 2012-07-16T01:10:02.030 回答
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 {}
...

你必须尝试这种方式。但在我看来,这还不够好。我认为会有一些错误或缺陷。

于 2012-07-09T06:33:35.997 回答
2

鉴于您的奴隶无法与主人更新的情况,您可能会遇到问题。因为在更新数据后,您可能会从旧版本中读取。

虽然论坛中给定的方法非常干净,并且由主要是 Yii 向导的作者编写。我也有另一种选择。您可以覆盖 AR 中的 getDbConnection() 方法,例如

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;
  }
}

但是在切换数据库连接的时候还是要小心的。

于 2012-07-16T22:08:37.053 回答