我有两个数据库连接,一个用于我的大多数应用程序数据,另一个用于读取。
虽然我可以将我的数据库用户帐户设置为仅允许读取,但还有其他人管理此系统,我希望在应用程序级别有一些冗余,以绝对防止使用Yii的标准ActiveRecord类进行意外写入。
在论坛上发现了这一点信息,但想知道是否有人可以确认这是一个好方法和/或建议另一个。
public function onBeforeSave($event)
{
$this->db = Yii::app()->masterDb;
}
public function onAfterSave($event)
{
$this->db = Yii::app()->db;
}
答案 0 :(得分:4)
根据您提供给Yii论坛的链接,有一个扩展程序可以为您处理: http://www.yiiframework.com/extension/dbreadwritesplitting
如果你有很多AR型号的话,我可能会先考虑一下。您可以将行为路线(如该论坛帖子中所示)作为另一种选择。
但是无论你做什么,你都希望在toSave / afterSave之前覆盖而不是onBeforeSave / onAfterSave。这些方法用于触发事件,而不仅仅是运行您自己的特殊代码。而且,根据another one of the forum posts,您需要使用静态调用设置AR db变量。所以谢尔盖的代码应该是:
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 {}
...
答案 1 :(得分: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 {}
...
你必须这样尝试:)但恕我直言,这还不够好。我认为会有一些错误或缺陷
答案 2 :(得分: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;
}
}
但是在切换数据库连接时你仍然需要小心。