Login | Register
My pages Projects Community openCollabNet

Discussions > dev > Improvement to Propel::setForceMasterConnection() behaviour

Discussion topic

Hide all messages in topic

All messages in topic

Improvement to Propel::setForceMasterConnection() behaviour


Author Shane Langley <shane dot langley at gmail dot com>
Full name Shane Langley <shane dot langley at gmail dot com>
Date 2008-09-24 15:26:33 PDT
Message Hi,

I'm using Propel in a master/slave environment and I've noticed a
possible issue with how Propel handles reads.

// i'd expect this to use master for ALL queries, not just rights

// gets the write connection (i.e master);
$conn = Propel::getConnection();

// I'd expect this query to hit the master since Propel has been forced
to use the master, but it hits the slave
$car = CarPeer::retrieveByPk(1);

Now I can easily get around this for this query by passing in $conn to
retreiveByPk() like so:

// this will hit the master
$car = CarPeer::retrieveByPk(1, $conn);

Which I guess is fine, but it gets a bit ugly needing to pass $conn
around to every accessor method.

Another issue is if you have a custom method which accesses a fk. If I
had this method in my Car class:

public function changeEngine(EngineType $newEngine)
    // this will access the foreign key for EngineType, and if it hasn't
been loading already, it'll hit the slave
    // even when forceMasterConnection is set to TRUE. Only way to get
around this is the pass in
    // $con to this method as well

    if ($this->getEngin​eType()->isChange​able())

So, my suggestion is the tweak the handling of connections for
master/slave setups.

This is the code used currently in SELECT methods:

if ($con === null) {
    $con = Propel::getConnectio​n(BidPeer::DATABASE_​NAME,

[Option 1]

Use ternary operator in relevant methods:

if ($con === null) {
    $con = Propel::getConnectio​n(BidPeer::DATABASE_​NAME,
(Propel::getForceMas​terConnection() ? Propel::CONNECTION_WRITE :

[Option 2]

Add new methods which way be easier to extend in the future. In the
Propel class:

 * Returns the connection to be used when writing
 * @return PropelPDO
public static function getWriteConnection($database)
    Propel::getConnectio​n($database, Propel::CONNECTION_WRITE);

 * Returns the connection to be used when selecting from the db.
 * This method will have different results based on the value of
Propel::$forceMasterConnection has been
 * set in a master/slave environment.
 * @return PropelPDO
public static function getReadConnection($database)
    if (Propel::getForceMas​terConnection()) {
        // master has been forced, use write connection
        return self::getWriteConnec​tion($database);

    // master not forced, so use read connection
    Propel::getConnectio​n($database, Propel::CONNECTION_READ);

Then the usage in query methods is a bit simpler:

SELECT methods:

if ($con === null) {
    $con = Propel::getReadConnection();


if ($con === null) {
    $con = Propel::getWriteConnection();

Messages per page: