Wednesday, June 16, 2010

SUCCESS at doing Bulk operations in Symfony

Well, after fighting my way through many pages, and many object methods that SEEMED like they would give me the opportunity to enclose a bulk load operation in a transaction, I finally found out how to do it.

DON'T get the PDO object from the Doctrine Library. Using it directly prevents Doctrine's 'Transaction' tree from keeping track of things. The PDO object might also not be connected yet depending on your context.

A good site for better laid out, and maybe better filled out documetation on Doctrine is: http://www.tig12.net/downloads/apidocs/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Doctrine_Manager.class.html#det_methods_connection

(That's a specific link to a specific item. I'll leave it as a reader's exercise to find their way to the home page of the site ;-) )

Anyway, reading through the documentation on that site, and examples of transactions for Symfony or Doctrine, I FINALLY found the crucial details.

A/ Use an instance of Doctrine_Connection to handle transactions external to the normal ORM statements that might be done for bulk loading.

B/ HOW TO GET THAT Doctrine_Connection instance while in a connected state.

And, drum roll please,this is how you do it:

$connection=Doctrine_Manager::connection(); // Doctrine_Manager is static.
//read link above to get info on how it automatically connects

$connection->beginTransaction();

//do bulk load stuff here, orrrrrrrrr
//roll your own save around all the elements of a complex schema save.
//For example.
//Books<->Authors database
//Authors can have multiple books
//Books can have multiple authors
//Three tables/objects in database
//Books, BookAuthors, Authors.
//To get them to save all at one

$book=new Book();
$book['author']='george';
$book['author']='dude';
$book->save();

//$book now has two authors.
//Internal code to books (and/or authors) that you have to write collects all the
//authors for books, or books for authors, and saves to all three tables, in between
// 'beginTransaction()' like above, and a 'commitTransaction()', like below.

$connection->beginTransaction();

Simplistic, and effective, but not complete. To do it right, you would put transaction inside of Book->save() method inside a try/catch block to catch database exceptions. See http://www.php.net/try and read all relevant links for 'catch', 'Exception', 'throw'

How this helps you.

EXTRA TIP.

Use arrays for data input and output as much as possible to save overhead

Set all variables to NULL at end of loops to help memory management and garbage collection in PHP.

No comments:

Post a Comment