2012-07-09 92 views
6

我有兩個數據庫連接,一個用於大多數應用程序數據,另一個僅用於讀取。Yii將數據庫連接限制爲只讀

雖然我可以設置我的數據庫用戶帳戶只允許讀取,但還有其他人在管理此係統,並且我希望在應用程序級別有一些冗餘以絕對防止使用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/

+2

使用單獨的數據庫用戶是明智的選擇。 – 2012-07-14 01:38:56

+1

@tereško...唯一的方式來充分保證,沒有未來的代碼打破這種「約定」... – Ron 2012-07-16 12:30:50

+0

我同意只讀數據庫用戶是最優雅的解決方案,但我想冗餘,因爲我不相信人管理系統100% – 2012-07-16 13:59:41

回答

4

每你的Yii的論壇上提供的鏈接,還有的是爲您處理此擴展: http://www.yiiframework.com/extension/dbreadwritesplitting

我可能會考慮,首先,如果你有很多AR模型。您可以選擇行爲路線(如該論壇帖子中的建議)作爲另一種選擇。

但無論你做什麼,你都希望在saveSave/afterSave而不是onBeforeSave/onAfterSave之後重寫。這些方法用於觸發事件,而不僅僅是運行自己的特殊代碼。而且,根據another one of the forum posts,您需要使用靜態調用來設置AR數據庫變量。所以謝爾蓋的代碼實際上應該是:

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

該擴展非常漂亮,我將不得不多讀一點。 – 2012-07-16 02:12:36

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必須嘗試這種方式:)但恕我直言這是不夠好。我認爲會有一些錯誤或缺陷

+0

感謝您將我離開我發佈的解決方案中的部分內容放入其中,以供任何其他人查看此問題的未來參考。你指的是什麼樣的錯誤/缺陷? – 2012-07-15 15:25:47

+0

@JohnZ,acorncom說:'onBeforeSave/onAfterSave。這些方法用於觸發事件,而不僅僅是運行自己的特殊代碼。這是我的意思。 – Sergey 2012-07-16 13:21:33

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

但切換數據庫連接時仍需小心。