Saving Same Record To Multiple Databases

Hi,

I need to save/update/delete all data of one of my ActiveRecord class to multiple databases.

I created base class SynchroAR that extends CActiveRecord:


public function getDbConnection() {

        if ($this->_currentDb !== null)

            return $this->_currentDb;

        else {

            return Yii::app()->usersdb;

        }

    }


    public function setDb($db = null) {

        if ($db === null) {

            $this->_currentDb = null;

            parent::$db->setActive(true);

        } else {

            $this->_currentDb = $db;

            $this->_currentDb->setActive(true);

        }

    }


    protected $_tempIsNewRecord;


    public function save($runValidation = true, $attributes = null) {

        if ($this->goSynchro) {

            $this->_tempIsNewRecord = true;

            $this->goSynchro = false;

            //first save in default db

            $this->setDb();

            $this->save($runValidation, $attributes);

            //then save in the others

            foreach ($this->entryConns as $conn) {

                $this->setDb($conn);

                if($this->_tempIsNewRecord)

                    $this->setIsNewRecord (true);

                $this->save($runValidation, $attributes);

            }

            $this->_tempIsNewRecord = false;

            $this->setDb();

            $this->goSynchro = true;

            return $this->_synchroResult;

        }

        else

            $this->_synchroResult = parent::save($runValidation, $attributes);

    }

Unfortunately when I try to add a new record - it adds in the default database but then - it doesn’t save the model in the 2nd database - validation says unique fields already exists. Why? How to achieve the goal?

Hi jozek

trace your code by this


public function getDbConnection() {

        if ($this->_currentDb !== null)

           {var_dump($this->_currentDb); return $this->_currentDb;}

        else {

            {var_dump(Yii::app()->usersdb;); return Yii::app()->usersdb;}

        }

    }

Hi KonApaz,

I cannot do a var_dump, cause it breaks the getDbConnection() method actually. I do Yii::trace(serialize($this->_currentDb)); instead.

It would use the correct database but (while debugging with Xdebug) I noticed that it uses always the default database while validation. That’s why it says the record already exists and doesn’t use the 2nd database.

I try to find a solution and share it with the community.

Is there a particular reason for this? Redundancies like these were a strong indicator for a major design flaw in my eyes.

Hi

For now I disabled validation for all databases without the default one. I assumed that if bases are synchronized validation can be run only once.

It works but I’d like to know whether the validators use the getDbConnection() method or they just call self::$db or sth? It was pretty obvious that the validators was validating the default database twice instead of validate 2nd base when I was trying to insert records to the 2nd database.

There is a particular reason to do that. This is pretty big and complicated system. The redundancy here is not a problem actually because the redundant data table is small (hundreds of records, but not thousands or millions) plus it’s being used quite rare. At the same time the redundancy here speeds everything up pretty much and as an addition it gives great failover in our case.

I adviced to trace this code to find out if the getDbConnection called on desired database connection before a query runs,

So according to what you said "I noticed that it uses always the default database" the getDbConnection not running as times you call an query?

how many records in Yii trace exist ?