ホームページ > バックエンド開発 > PHPチュートリアル > Yii は複数のデータベースでマスターとスレーブの読み取りと書き込みを分離する方法を実装します。yii データベースのマスターとスレーブの読み取りと書き込み_PHP チュートリアル

Yii は複数のデータベースでマスターとスレーブの読み取りと書き込みを分離する方法を実装します。yii データベースのマスターとスレーブの読み取りと書き込み_PHP チュートリアル

WBOY
リリース: 2016-07-13 10:10:31
オリジナル
840 人が閲覧しました

Yii は、複数のデータベースでマスターとスレーブの読み取りと書き込みを分離する方法、yii データベースのマスターとスレーブの読み取りと書き込みを実装します

この記事の例では、Yii が複数のデータベースでマスターとスレーブの読み取りと書き込みの分離を実装する方法を説明します。参考のためにみんなで共有してください。具体的な分析は次のとおりです:

Yii フレームワーク データベース マルチデータベース、マスター/スレーブ、読み書き分離実装、機能説明:

1. マスター/スレーブ データベースの読み取りと書き込みの分離を実現します。スレーブ データベース (複数可): 読み取り

2. マスターデータベースに接続できない場合、スレーブデータベースに書き込み可能かどうかを設定できます

3. すべてのスレーブデータベースに接続できない場合、マスターデータベースを読み取り可能にするかどうかを設定できます

4. データベースからの接続が失敗した場合、N 秒以内に再接続しないように設定できます

yii 拡張機能を使用して実装すると、コードは次のようになります:

コードをコピーします コードは次のとおりです:
/**
* メインデータベースはデータベースへの書き込みとデータベースからの読み取りを行います (複数の可能性があります)
* マスター/スレーブデータベースでの読み取りと書き込みの分離を実現します。マスターサーバーは接続できず、スレーブサーバーは書き込み機能を切り替えることができます
※スレーブサーバーは接続できません。マスターサーバーは読み取り機能を切り替えることができます
*lmtによる
**/
class DbConnectionMan extends CDbConnection {
パブリック $timeout = 10 //接続タイムアウト
; Public $markDeadSeconds = 600; //データベースからの接続が失敗した場合、600 秒以内にそれ以上の接続は行われません
//キャッシュをキャッシュグローバルタグとして使用します
パブリック $cacheID = 'キャッシュ';
/**
     * @var array $slaves.Slave データベース接続 (読み取り) 構成配列。
     * 構成符合 CDbConnection。
     * @例
     * 'コンポーネント'=>array(
     * 'db'=>array(
     * 'connectionString'=>'mysql://',
     * 'スレーブ'=>array(
     * array('connectionString'=>'mysql://')、
     * array('connectionString'=>'mysql://')、
     * )
     * )
     *)
     **/
パブリック $slaves = array(); /**
* *
* スレーブデータベースのステータスが false の場合、マスターデータベースのみが使用されます
* @var bool $enableSlave
**/
パブリック $enableSlave = true

/**
* @var smilesWrite 緊急マスターデータベースに接続できません。スレーブサーバーを切り替えます (読み取りおよび書き込み)。 ​​*/
パブリック $slavesWrite = false

/**
* @var masterRead 緊急の場合、スレーブマスターデータベースに接続できない場合は、スレーブサーバー(読み取りおよび書き込み)に切り替えます。 ​​*/
パブリック $masterRead = false;
/**
     * @var _slave
    */
プライベート $_スレーブ

/**
* @var _disableWrite スレーブ (読み取り専用)
​​*/
プライベート $_disableWrite = true

/**
*
* createCommand メソッドを書き換えます。 1. スレーブ ライブラリを開く 2. スレーブ ライブラリから存在する 3. 現在トランザクション中ではない 4. ライブラリからデータを読み取る
* @param 文字列 $sql
* @return CDbCommand
**/
パブリック関数 createCommand($sql = null) {
if ($this->enableSlave && !emptyempty($this->slaves) && is_string($sql) && !$this->getCurrentTransaction() && self::isReadOperation($sql) && ($slave = $ this->getSlave())
) {
return $slave->createCommand($sql); } else {
If (!$this->masterRead) {
If ($this->_disableWrite && !self::isReadOperation($sql)) {

throw new CDbException("マスター データベース サーバーは現在使用できません! スレーブ サーバーでの書き込み操作を禁止します!");                                                                                                                                                                      returnparent::createCommand($sql); }
}

/**
* サーバーから接続リソースを取得します
* @return CDbConnection
**/
パブリック関数 getSlave() {
        if (!isset($this->_slave)) {
            シャッフル($this->スレーブ);
            foreach ($this->slaves as $slaveConfig) {
                if ($this->_isDeadServer($slaveConfig['connectionString'])) {
                    続く;
                }
                if (!isset($slaveConfig['class']))
                    $slaveConfig['クラス'] = 'CDbConnection';
 
                $slaveConfig['autoConnect'] = false;
                {
を試してください                     if ($slave = Yii::createComponent($slaveConfig)) {
                        Yii::app()->setComponent('dbslave', $slave);
                        $slave->setAttribute(PDO::ATTR_TIMEOUT, $this->timeout);
                        $slave->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
                        $slave->setActive(true);
                        $this->_slave = $slave;
                        壊す;
                    }
                } catch (例外 $e) {
                    $this->_markDeadServer($slaveConfig['connectionString']);
                    Yii::log("スレーブ データベース接続に失敗しました!ntConnection string:{$slaveConfig['connectionString']}", 'warning');
 
                    続く;
                }
            }
 
            if (!isset($this->_slave)) {
                $this->_slave = null;
                $this->enableSlave = false;
            }
        }
        $this->_slave を返します;
    }
 
    パブリック関数 setActive($value) {
        if ($value != $this->getActive()) {
            if ($value) {
                {
を試してください                     if ($this->_isDeadServer($this->connectionString)) {
                        throw new CDbException('マスター データベース サーバーはすでに停止しています!');
                    }
                    //PDO::ATTR_TIMEOUT は PDO インスタンスを作成する前に設定する必要があります
                    $this->setAttribute(PDO::ATTR_TIMEOUT, $this->timeout);
                    $this->open();
                } catch (例外 $e) {
                    $this->_markDeadServer($this->connectionString);
                    $slave = $this->getSlave();
                    Yii::log($e->getMessage(), CLogger::LEVEL_ERROR, '例外.CDbException');
                    if ($slave) {
                        $this->接続文字列 = $slave->接続文字列;
                        $this->ユーザー名 = $slave->ユーザー名;
                        $this->パスワード = $slave->パスワード;
                        if ($this->slavesWrite) {
                            $this->_disableWrite = false;
                        }
                        $this->open();
                    } else { //スレーブも利用できません
                        if ($this->masterRead) {
                            $this->接続文字列 = $this->接続文字列;
                            $this->ユーザー名 = $this->ユーザー名;
                            $this->パスワード = $this->パスワード;
                            $this->open();
                        } その他 {
                            throw new CDbException(Yii::t('yii', 'CDbConnection が DB 接続をオープンできませんでした。'), (int) $e->getCode(), $e->errorInfo);
                        }
                    }
                }
            } その他 {
                $this->close();
            }
        }
    }
 
    /**
* 読み取り操作 SQL ステートメントを検出します
* *
* キーワード: 選択、記述、表示...
* 書き込み操作: UPDATE、INSERT、DELETE...
**/
    パブリック静的関数 isReadOperation($sql) {
        $sql = substr(ltrim($sql), 0, 10);
        $sql = str_ireplace(array('SELECT', 'SHOW', 'DESCRIBE', 'PRAGMA'), '^O^', $sql); //^O^、魔法の笑顔
        strpos($sql, '^O^') === 0 を返します。
    }
 
    /**
* スレーブサーバーが
マークされているかどうかの検出に失敗しました。 ​​*/
    プライベート関数 _isDeadServer($c) {
        $cache = Yii::app()->{$this->キャッシュID};
        if ($cache && $cache->get('DeadServer::' . $c) == 1) {
            true を返します。
        }
        false を返します。
    }
 
    /**
* 失敗した奴隷をマークします
​​*/
    プライベート関数 _markDeadServer($c) {
        $cache = Yii::app()->{$this->キャッシュID};
        if ($cache) {
            $cache->set('DeadServer::' . $c, 1, $this->markDeadSeconds);
        }
    }
}

main.php 構成:components 数组中,代码如下:
复制代码代码如下:
'db'=>array(
'class'=>'application.extensions.DbConnectionMan',//拡張パス
'connectionString' => 'mysql:host=192.168.1.128;dbname=db_xcpt',//メインデータベース書き込み
'emulatePrepare' => true、
'ユーザー名' => 'root'、
「パスワード」 => 「root」、
'charset' => 'utf8'、
'tablePrefix' => 'xcpt_', //テーブルプレフィックス
'enableSlave'=>true,//データベースから有効にする
'urgencyWrite'=>true,//緊急時には、メインデータベースに接続できなくなります。スレーブデータベースの書き込み機能を有効にします
。 'masterRead'=>true,//緊急事態 スレーブデータベースに接続できません マスターデータベース読み取り機能を有効にします
'slaves'=>array(//データベースより
array( //スレーブ1
'connectionString'=>'mysql:host=localhost;dbname=db_xcpt',
'emulatePrepare' => true、
'ユーザー名'=>'root'、
'パスワード'=>'root',
'charset' => 'utf8'、
'tablePrefix' => 'xcpt_', //テーブルのプレフィックス
)、
array( //スレーブ2
'connectionString'=>'mysql:host=localhost;dbname=db_xcpt',
'emulatePrepare' => true、
'ユーザー名'=>'root'、
'パスワード'=>'root',
'charset' => 'utf8'、
'tablePrefix' => 'xcpt_', //テーブルのプレフィックス
)、

)、
)、

この記事が皆さんの Yii フレームワークに基づく PHP プログラミングに役立つことを願っています。

www.bkjia.com本当http://www.bkjia.com/PHPjc/934930.html技術記事 Yii による複数データベースのマスター・スレーブ読み書き分離を実現する方法 Yii データベースのマスター・スレーブ読み書き・書き込み この記事では、Yii による複数データベースのマスター・スレーブ読み書き分離を実現する方法の例について説明します。参考のためにみんなで共有してください。ツール...
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート