Learning CakePHP

March 28, 2011

Using Different Database Configurations for Reading/Writing Data

Filed under: CakePHP How-To's, Idiot's Guide — Tags: , , — ldazo @ 12:08 pm

When dealing with applications using large database plus numerous scripts on the background that constantly reads/writes data to the same database server, one of the problems we usually encounter is that tables get locked up during one of the processes. This causes our application to slow down. In this case, it is often necessary to separate database calls. Set up a slave DB with a user with read-only privileges, and which is constantly being synched with the master DB.

To make this work in cakePHP, you need to set-up two db configs. Define ur /config/database.php as such:

class DATABASE_CONFIG {
var $default = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'port' => '' ,
'login' => '*****',
'password' => '****',
'database' => '****',
'schema' => '',
'prefix' => **_',
'encoding' => ''
);
var $master = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'port' => '' ,
'login' => '****',
'password' => '****',
'database' => '*****',
'schema' => '',
'prefix' => '**_',
'encoding' => ''
);

}

The default configuration always uses the Slave DB. For security reasons, make sure that the login is set to a user with a read-only privilege.

Now create an app_model.php file. Create the following functions that shall override the parent model class:


function save($data = null, $validate = true, $fieldList = array())
{
$this->setDataSource('master');
$isSave = parent::save($data, $validate, $fieldList);
$this->setDataSource('default');
return $isSave;
}


function saveAll($data = null, $options = array())
{
$this->setDataSource('master');
$isSave = parent::save($data, $options);
$this->setDataSource('default');

return $isSave;
}


function updateAll($fields, $conditions=true)
{
$this->setDataSource('master');
$isUpdated = parent::updateAll($fields, $conditions);
$this->setDataSource('default');

return $isUpdated;
}


function delete($id = null, $cascade = true)
{
$this->setDataSource('master');
$isDeleted = parent::delete($id, $cascade);
$this->setDataSource('default');

return $isDeleted;
}


function deleteAll($conditions, $cascade = true, $callbacks = false)
{
$this->setDataSource('master');
$isDeleted = parent::deleteAll($conditions, $cascade, $callbacks);
$this->setDataSource('default');

return $isDeleted;
}

For a more complicated db setup, wherein you have multiple slave databases to access data from you could refer to my actual source here.

Advertisement

2 Comments »

  1. Behavior can do this in cleaner way using
    beforeSave and beforeDelete callbacks

    Comment by majna — April 8, 2011 @ 2:06 pm

    • i tried that [doing beforeSave and beforeDelete] already but it did not work for me.
      and when you say ‘cleaner’ i could argue back that this code is ‘clean’ too. Rather, the comparison fails when the other option does not work for me. If you would be kind enough to show me how you did yours, that’d be a great help :)

      Comment by ldazo — May 27, 2011 @ 3:33 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.