Location: PHPKode > projects > Swat > Swat-1.4.108/Swat-1.4.108/SwatDB/SwatDBTransaction.php
<?php

/* vim: set noexpandtab tabstop=4 shiftwidth=4 foldmethod=marker: */

require_once 'MDB2.php';
require_once 'Swat/SwatObject.php';
require_once 'SwatDB/exceptions/SwatDBException.php';

/**
 * A database transaction that is safe to use with database drivers that do
 * not support nested transactions
 *
 * Example use:
 * <code>
 * $transaction = new SwatDBTransaction($database);
 * try {
 *     SwatDB::query($database, $sql);
 * } catch (SwatDBException $e) {
 *     $transaction->rollback();
 *     throw $e;
 * }
 * $transaction->commit();
 * </code>
 *
 * @package   SwatDB
 * @copyright 2006 silverorange
 * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
 */
class SwatDBTransaction extends SwatObject
{
	// {{{ private properties

	/**
	 * The database driver object to perform the transaction with
	 *
	 * @var MDB2_Driver_Common
	 */
	private $db;

	/**
	 * Whether or not this database transaction exists inside another database
	 * transaction (nested)
	 *
	 * @var boolean
	 */
	private $in_another_transaction;

	/**
	 * Whether or not this transaction is finished
	 *
	 * A transaction is finished after either it is either successfully
	 * committed or it is successfully rolled-back.
	 *
	 * @var boolean
	 */
	private $finished;

	// }}}
	// {{{ public function __construct()

	/**
	 * Begins a new database transaction
	 *
	 * For databases that do not support nested transactions, this method
	 * prevents opening a new transaction if we are already in a transaction.
	 *
	 * @param MDB2_Driver_Common the database connection to perform the
	 *                            transaction with.
	 */
	public function __construct(MDB2_Driver_Common $db)
	{
		$this->db = $db;
		$this->in_another_transaction = ($this->db->in_transaction);
		if (!$this->in_another_transaction)
			$this->db->beginTransaction();
	}

	// }}}
	// {{{ public function commit()

	/**
	 * Commits this database transaction
	 *
	 * For databases that do not support nested transactions, this method
	 * prevents comitting a transaction if we are already inside another
	 * transaction.
	 */
	public function commit()
	{
		if ($this->finished) {
			throw new SwatDBException('Transaction objects cannot be reused. '.
				'Create a new SwatDBTransaction object to begin a new '.
				'transaction.');
		} else {
			if (!$this->in_another_transaction)
				$this->db->commit();

			$this->finished = true;
		}
	}

	// }}}
	// {{{ public function rollback()

	/**
	 * Rolls-back this database transaction
	 *
	 * For databases that do not support nested transactions, this method
	 * prevents rolling-back a transaction if we are already inside another
	 * transaction.
	 */
	public function rollback()
	{
		if ($this->finished) {
			throw new SwatDBException('Transaction objects cannot be reused. '.
				'Create a new SwatDBTransaction object to begin a new '.
				'transaction.');
		} else {
			if (!$this->in_another_transaction)
				$this->db->rollback();

			$this->finished = true;
		}
	}

	// }}}
}

?>
Return current item: Swat