6

2 つのデータベース接続があります。1 つはほとんどのアプリケーション データに使用され、もう 1 つは読み取り専用です。

読み取りのみを許可するようにデータベース ユーザー アカウントをセットアップすることはできますが、このシステムを管理している人が他にもいるため、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モデルがたくさんある場合は、おそらく最初にそれを調べます。別のオプションとして、行動ルート (そのフォーラムの投稿で提案されているように) に進むことができます。

しかし、何をするにしても、onBeforeSave / onAfterSave の代わりに beforeSave / afterSave をオーバーライドしたいと思うでしょう。これらのメソッドは、独自の特別なコードを実行するだけでなく、イベントをトリガーするためのものです。また、別のフォーラム投稿によると、静的呼び出しを使用して 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 {}
...
于 2012-07-16T01:10:02.030 に答える
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 に答える
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 に答える