Source for file Transaction.php
Documentation is available at Transaction.php
* $Id: Transaction.php 2268 2007-08-24 21:43:50Z jackbravo $
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
* Handles transaction savepoint and isolation abstraction
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @version $Revision: 2268 $
* Doctrine_Transaction is in sleep state when it has no active transactions
* Doctrine_Transaction is in active state when it has one active transaction
* Doctrine_Transaction is in busy state when it has multiple active transactions
* @var integer $transactionLevel the nesting level of transactions, used by transaction methods
* @var array $invalid an array containing all invalid records within this transaction
* @var array $delete two dimensional pending delete list, the records in
* this list will be deleted when transaction is committed
* @var array $savepoints an array containing all savepoints
* @var array $_collections an array of Doctrine_Collection objects that were affected during the Transaction
* adds a collection in the internal array of collections
* at the end of each commit this array is looped over and
* of every collection Doctrine then takes a snapshot in order
* to keep the collections up to date with the database
* @param Doctrine_Collection $coll a collection to be added
* @return Doctrine_Transaction this object
* returns the state of this connection
* @see Doctrine_Connection_Transaction::STATE_* constants
* @return integer the connection state
* adds record into pending delete list
* @param Doctrine_Record $record a record to be added
public function addDelete(Doctrine_Record $record)
$name =
$record->getTable()->getComponentName();
$this->delete[$name][] =
$record;
* adds record into invalid records list
* @param Doctrine_Record $record
* @return boolean false if record already existed in invalid records list,
public function addInvalid(Doctrine_Record $record)
* returns the pending delete list
* deletes all records from the pending delete list
foreach ($this->delete as $name =>
$deletes) {
if (is_array($deletes[count($deletes)-
1]->getTable()->getIdentifier())) {
if (count($deletes) >
0) {
.
$this->conn->quoteIdentifier($deletes[0]->getTable()->getTableName())
foreach ($deletes as $k =>
$record) {
$ids =
$record->identifier();
$cond[] =
'(' .
implode(' AND ', $tmp) .
')';
$this->conn->execute($query, $params);
foreach ($deletes as $k =>
$record) {
$ids[] =
$record->getIncremented();
.
$this->conn->quoteIdentifier($record->getTable()->getTableName())
.
$record->getTable()->getIdentifier()
.
' IN(' .
$params .
')';
$this->conn->execute($query, $ids);
* get the current transaction nesting level
* set the current transaction nesting level
* @return Doctrine_Transaction this object
* Start a transaction or set a savepoint.
* if trying to set a savepoint and there is no active transaction
* a new transaction is being started
* Listeners: onPreTransactionBegin, onTransactionBegin
* @param string $savepoint name of a savepoint to set
* @throws Doctrine_Transaction_Exception if the transaction fails at database level
* @return integer current transaction nesting level
$listener =
$this->conn->getAttribute(Doctrine::ATTR_LISTENER);
$listener->preSavepointCreate($event);
if ( ! $event->skipOperation) {
$listener->postSavepointCreate($event);
$listener->preTransactionBegin($event);
if ( ! $event->skipOperation) {
$this->conn->getDbh()->beginTransaction();
$listener->postTransactionBegin($event);
* Commit the database changes done during a transaction that is in
* progress or release a savepoint. This function may only be called when
* auto-committing is disabled, otherwise it will fail.
* Listeners: preTransactionCommit, postTransactionCommit
* @param string $savepoint name of a savepoint to release
* @throws Doctrine_Transaction_Exception if the transaction fails at database level
* @throws Doctrine_Validator_Exception if the transaction fails due to record validations
* @return boolean false if commit couldn't be performed, true otherwise
public function commit($savepoint =
null)
$listener =
$this->conn->getAttribute(Doctrine::ATTR_LISTENER);
$listener->preSavepointCommit($event);
if ( ! $event->skipOperation) {
$listener->postSavepointCommit($event);
$listener->preTransactionCommit($event);
if ( ! $event->skipOperation) {
// take snapshots of all collections used within this transaction
$this->conn->getDbh()->commit();
//$this->conn->unitOfWork->reset();
$listener->postTransactionCommit($event);
* Cancel any database changes done during a transaction or since a specific
* savepoint that is in progress. This function may only be called when
* auto-committing is disabled, otherwise it will fail. Therefore, a new
* transaction is implicitly started after canceling the pending changes.
* this method can be listened with onPreTransactionRollback and onTransactionRollback
* @param string $savepoint name of a savepoint to rollback to
* @throws Doctrine_Transaction_Exception if the rollback operation fails at database level
* @return boolean false if rollback couldn't be performed, true otherwise
public function rollback($savepoint =
null)
$listener =
$this->conn->getAttribute(Doctrine::ATTR_LISTENER);
$listener->preSavepointRollback($event);
if ( ! $event->skipOperation) {
$listener->postSavepointRollback($event);
$listener->preTransactionRollback($event);
if ( ! $event->skipOperation) {
$this->deteles =
array();
$this->conn->getDbh()->rollback();
$listener->postTransactionRollback($event);
* creates a new savepoint
* @param string $savepoint name of a savepoint to create
* releases given savepoint
* @param string $savepoint name of a savepoint to release
* releases given savepoint
* @param string $savepoint name of a savepoint to rollback to
* removes a savepoint from the internal savePoints array of this transaction object
* and all its children savepoints
* @param sring $savepoint name of the savepoint to remove
* @return integer removed savepoints
if ($sp ===
$savepoint) {
* Set the transacton isolation level.
* (implemented by the connection drivers)
* $tx->setIsolation('READ UNCOMMITTED');
* @param string standard isolation level
* READ UNCOMMITTED (allows dirty reads)
* READ COMMITTED (prevents dirty reads)
* REPEATABLE READ (prevents nonrepeatable reads)
* SERIALIZABLE (prevents phantom reads)
* @throws Doctrine_Transaction_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* getTransactionIsolation
* fetches the current session transaction isolation level
* note: some drivers may support setting the transaction isolation level
* @throws Doctrine_Transaction_Exception if the feature is not supported by the driver
* @throws PDOException if something fails at the PDO level
* @return string returns the current session transaction isolation level