I tried to use several transactions in Doctrine (v1.2.2). Here my test:
// Open a new database connection
$cnx1 = Doctrine_Manager::connection('mydsn'); // $cnx1 will be named '0'
// Open a second database connection
$cnx2 = Doctrine_Manager::connection('mydsn'); // $cnx2 will be named '1'
// Start a transaction on connection #1
$cnx1->beginTransaction();
// Update the name of user #1
$query1 = $cnx1->createQuery();
$query1->update('SfGuardUser')->set("username", "'Name 1'")->where("id='1'");
$query1->execute();
// Start an other transaction on connection #2
$cnx2->beginTransaction();
// Update the name of user #2
$query2 = $cnx2->createQuery();
$query2->update('SfGuardUser')->set("username", "'Name 2'")->where("id='2'");
$query2->execute();
// Commit transaction #2
$cnx2->commit();
(The default isolation level is REPEATABLE READ.)
After running the code, both user names have changed in the database. According to me, only the name of user #2 should be modified, as the transaction #1 has not yet been committed.
When debugging, I saw that it is always the connection #2 (the last opened) which is used for all queries. Why ?
In the Doctrine documentation, we can read "From the start Doctrine has been designed to work with multiple connections. Unless separately specified Doctrine always uses the current connection for ex开发者_运维百科ecuting the queries."
How to do to use different connections and uniques transactions?
I believe this is a bug in Doctrine (still there in the current 1.2 release, as far as I can tell). When you create a query from Doctrine_Connection::createQuery(), it does not pass itself to the query as the first parameter, so it is always created on the default connection.
The bugfix should be a simple one, passing in $this to Doctrine_Query::create() in Doctrine_Connection.
A workaround is to create the query yourself, and pass in the connection:
$query1 = Doctrine_Query::create($cnx1);
$query2 = Doctrine_Query::create($cnx2);
精彩评论