Mike, on 03 December 2009 - 04:31 AM, said:
Hmm. Isn't that exactly what the above class does?
I only see a problem with e.g. saveAttributes() as it doesn't call beforeSave(). So you could also override this method in the class above:
<?php
public function saveAttributes($attributes) {
$this->switchToWriter();
$ret=parent::saveAttributes($attributes);
$this->switchToReader();
return $ret;
}
There might be more methods, didn't check thoroughly.
Another thing: If you use before/afterSave/Delete() in an AR you must call parent::* there, otherwhise the events wont be raised.
The problem is that the switching happens automagically behind the scenes. A master-slave configuration is all find and dandy up until the point that the slave replication gets behind the master. I have worked with configurations that - because the slave is on a less powerful machine - can get very far behind during peak hours. In these situations an automatic configuration that switches between the master and slave for reads and writes is *NOT* what you want. You would save data to the master, redirect to the next page that needs to read and reference that information, and it wouldn't exist because of the latency between slave and master.
There needs to be a way to force the application to use a specific database, you cannot limit reads to only be able to happen on the slave. You do need to read off of the master sometimes.
As such, my programming philosophy is that all reads/writes happen on the master unless I, the developer, tell the application to do otherwise. This is something as simple as calling "$db->useSlave();" before executing my query. At this point, the database will remain reading from the slave until I call "$db->useMaster();", "$db->reset();", or page execution completes.
If you explicitly tell the application which database to use, then you won't run into magic ghost bugs with missing data that you can never trace down because the database with which you are interfacing transparently changes mid-transaction. Believe me, I have run into very time costly and hard to fix bugs when I had an application that automated the slave/master exchange.
Now, on that same note. If you want your application to read from the slave and write to the master by default, then that isn't necessarily a problem, and has it's benefits. If you have an application that will mostly be doing non time sensitive reads then it makes sense to use the slave by default. However, you *NEED* some way of forcing the application to be able to read from the master. If you have no way of manually forcing which database connection you use for a given query, you are setting yourself up for inevitable disaster that could be very costly to you in the future.