From b12b8b0041f30aed05ff87a16d3c21de135bcfc8 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 6 May 2010 18:39:19 -0300 Subject: [PATCH] Revertd partially the support to DBAL\Transaction, it was wrong. Fixed implementation of ORM\EntityTransaction and fixed tests. --- lib/Doctrine/DBAL/Connection.php | 210 ++++++++++++++-- lib/Doctrine/DBAL/Driver/.DS_Store | Bin 0 -> 6148 bytes lib/Doctrine/DBAL/Driver/Connection.php | 3 + .../DBAL/Driver/OCI8/OCI8Connection.php | 2 +- lib/Doctrine/DBAL/Driver/PDOConnection.php | 2 +- lib/Doctrine/DBAL/Driver/Transaction.php | 42 ---- .../DBAL/Platforms/AbstractPlatform.php | 15 +- .../DBAL/Platforms/OraclePlatform.php | 8 +- .../DBAL/Platforms/SqlitePlatform.php | 8 +- lib/Doctrine/DBAL/Transaction.php | 229 ------------------ lib/Doctrine/ORM/EntityManager.php | 9 +- lib/Doctrine/ORM/EntityTransaction.php | 49 ++-- lib/Doctrine/ORM/UnitOfWork.php | 2 +- .../Tests/DBAL/Functional/AllTests.php | 2 +- .../Tests/DBAL/Functional/ConnectionTest.php | 64 +++++ .../Tests/DBAL/Functional/TransactionTest.php | 68 ------ .../DBAL/Platforms/MsSqlPlatformTest.php | 8 +- .../DBAL/Platforms/MySqlPlatformTest.php | 8 +- .../DBAL/Platforms/OraclePlatformTest.php | 8 +- .../DBAL/Platforms/PostgreSqlPlatformTest.php | 9 +- .../DBAL/Platforms/SqlitePlatformTest.php | 20 +- 21 files changed, 337 insertions(+), 429 deletions(-) create mode 100644 lib/Doctrine/DBAL/Driver/.DS_Store delete mode 100644 lib/Doctrine/DBAL/Driver/Transaction.php delete mode 100644 lib/Doctrine/DBAL/Transaction.php create mode 100644 tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php delete mode 100644 tests/Doctrine/Tests/DBAL/Functional/TransactionTest.php diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index bf1e7b0e4..9ed6292ca 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -42,6 +42,26 @@ use PDO, Closure, */ class Connection implements DriverConnection { + /** + * Constant for transaction isolation level READ UNCOMMITTED. + */ + const TRANSACTION_READ_UNCOMMITTED = 1; + + /** + * Constant for transaction isolation level READ COMMITTED. + */ + const TRANSACTION_READ_COMMITTED = 2; + + /** + * Constant for transaction isolation level REPEATABLE READ. + */ + const TRANSACTION_REPEATABLE_READ = 3; + + /** + * Constant for transaction isolation level SERIALIZABLE. + */ + const TRANSACTION_SERIALIZABLE = 4; + /** * The wrapped driver connection. * @@ -66,6 +86,20 @@ class Connection implements DriverConnection */ private $_isConnected = false; + /** + * The transaction nesting level. + * + * @var integer + */ + private $_transactionNestingLevel = 0; + + /** + * The currently active transaction isolation level. + * + * @var integer + */ + private $_transactionIsolationLevel; + /** * The parameters used during creation of the Connection instance. * @@ -94,14 +128,14 @@ class Connection implements DriverConnection * @var Doctrine\DBAL\Driver */ protected $_driver; - - /** - * The DBAL Transaction. - * - * @var Doctrine\DBAL\Transaction - */ - protected $_transaction; + /** + * Flag that indicates whether the current transaction is marked for rollback only. + * + * @var boolean + */ + private $_isRollbackOnly = false; + /** * Initializes a new instance of the Connection class. * @@ -132,7 +166,6 @@ class Connection implements DriverConnection $this->_config = $config; $this->_eventManager = $eventManager; - if ( ! isset($params['platform'])) { $this->_platform = $driver->getDatabasePlatform(); } else if ($params['platform'] instanceof Platforms\AbstractPlatform) { @@ -140,8 +173,7 @@ class Connection implements DriverConnection } else { throw DBALException::invalidPlatformSpecified(); } - - $this->_transaction = new Transaction($this); + $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel(); } /** @@ -244,16 +276,6 @@ class Connection implements DriverConnection return $this->_platform; } - /** - * Gets the DBAL Transaction instance. - * - * @return Doctrine\DBAL\Transaction - */ - public function getTransaction() - { - return $this->_transaction; - } - /** * Establishes the connection with the database. * @@ -288,8 +310,9 @@ class Connection implements DriverConnection * @param string $statement The SQL query. * @param array $params The query parameters. * @return array + * @todo Rename: fetchAssoc */ - public function fetchAssoc($statement, array $params = array()) + public function fetchRow($statement, array $params = array()) { return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_ASSOC); } @@ -331,6 +354,16 @@ class Connection implements DriverConnection return $this->_isConnected; } + /** + * Checks whether a transaction is currently active. + * + * @return boolean TRUE if a transaction is currently active, FALSE otherwise. + */ + public function isTransactionActive() + { + return $this->_transactionNestingLevel > 0; + } + /** * Executes an SQL DELETE statement on a table. * @@ -365,6 +398,28 @@ class Connection implements DriverConnection $this->_isConnected = false; } + /** + * Sets the transaction isolation level. + * + * @param integer $level The level to set. + */ + public function setTransactionIsolation($level) + { + $this->_transactionIsolationLevel = $level; + + return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level)); + } + + /** + * Gets the currently active transaction isolation level. + * + * @return integer The current transaction isolation level. + */ + public function getTransactionIsolation() + { + return $this->_transactionIsolationLevel; + } + /** * Executes an SQL UPDATE statement on a table. * @@ -528,10 +583,10 @@ class Connection implements DriverConnection * represents a row of the result set. * @return mixed The projected result of the query. */ - public function project($query, array $params, Closure $function) + public function project($query, array $params = array(), Closure $function) { $result = array(); - $stmt = $this->executeQuery($query, $params ?: array()); + $stmt = $this->executeQuery($query, $params); while ($row = $stmt->fetch()) { $result[] = $function($row); @@ -602,6 +657,16 @@ class Connection implements DriverConnection return $this->_conn->exec($statement); } + /** + * Returns the current transaction nesting level. + * + * @return integer The nesting level. A value of 0 means there's no active transaction. + */ + public function getTransactionNestingLevel() + { + return $this->_transactionNestingLevel; + } + /** * Fetch the SQLSTATE associated with the last database operation. * @@ -641,6 +706,73 @@ class Connection implements DriverConnection return $this->_conn->lastInsertId($seqName); } + /** + * Starts a transaction by suspending auto-commit mode. + * + * @return void + */ + public function beginTransaction() + { + $this->connect(); + + if ($this->_transactionNestingLevel == 0) { + $this->_conn->beginTransaction(); + } + + ++$this->_transactionNestingLevel; + } + + /** + * Commits the current transaction. + * + * @return void + * @throws ConnectionException If the commit failed due to no active transaction or + * because the transaction was marked for rollback only. + */ + public function commit() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::commitFailedNoActiveTransaction(); + } + if ($this->_isRollbackOnly) { + throw ConnectionException::commitFailedRollbackOnly(); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + $this->_conn->commit(); + } + + --$this->_transactionNestingLevel; + } + + /** + * Cancel any database changes done during the current transaction. + * + * this method can be listened with onPreTransactionRollback and onTransactionRollback + * eventlistener methods + * + * @throws ConnectionException If the rollback operation failed. + */ + public function rollback() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::rollbackFailedNoActiveTransaction(); + } + + $this->connect(); + + if ($this->_transactionNestingLevel == 1) { + $this->_transactionNestingLevel = 0; + $this->_conn->rollback(); + $this->_isRollbackOnly = false; + } else { + $this->_isRollbackOnly = true; + --$this->_transactionNestingLevel; + } + } + /** * Gets the wrapped driver connection. * @@ -657,7 +789,7 @@ class Connection implements DriverConnection * Gets the SchemaManager that can be used to inspect or change the * database schema through the connection. * - * @return Doctrine\DBAL\Schema\AbstractSchemaManager + * @return Doctrine\DBAL\Schema\SchemaManager */ public function getSchemaManager() { @@ -668,6 +800,34 @@ class Connection implements DriverConnection return $this->_schemaManager; } + /** + * Marks the current transaction so that the only possible + * outcome for the transaction to be rolled back. + * + * @throws ConnectionException If no transaction is active. + */ + public function setRollbackOnly() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + $this->_isRollbackOnly = true; + } + + /** + * Check whether the current transaction is marked for rollback only. + * + * @return boolean + * @throws ConnectionException If no transaction is active. + */ + public function getRollbackOnly() + { + if ($this->_transactionNestingLevel == 0) { + throw ConnectionException::noActiveTransaction(); + } + return $this->_isRollbackOnly; + } + /** * Converts a given value to its database representation according to the conversion * rules of a specific DBAL mapping type. @@ -751,4 +911,4 @@ class Connection implements DriverConnection } } } -} +} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/.DS_Store b/lib/Doctrine/DBAL/Driver/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0. - */ - -namespace Doctrine\DBAL\Driver; - -/** - * Transaction interface. - * Each Driver Connection must implement this interface. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - */ -interface Transaction -{ - function beginTransaction(); - function commit(); - function rollBack(); -} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index ba9c047d1..87b26f3c6 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -23,7 +23,6 @@ namespace Doctrine\DBAL\Platforms; use Doctrine\DBAL\DBALException, Doctrine\DBAL\Connection, - Doctrine\DBAL\Transaction, Doctrine\DBAL\Types, Doctrine\DBAL\Schema\Table, Doctrine\DBAL\Schema\Index, @@ -1457,13 +1456,13 @@ abstract class AbstractPlatform protected function _getTransactionIsolationLevelSQL($level) { switch ($level) { - case Transaction::READ_UNCOMMITTED: + case Connection::TRANSACTION_READ_UNCOMMITTED: return 'READ UNCOMMITTED'; - case Transaction::READ_COMMITTED: + case Connection::TRANSACTION_READ_COMMITTED: return 'READ COMMITTED'; - case Transaction::REPEATABLE_READ: + case Connection::TRANSACTION_REPEATABLE_READ: return 'REPEATABLE READ'; - case Transaction::SERIALIZABLE: + case Connection::TRANSACTION_SERIALIZABLE: return 'SERIALIZABLE'; default: throw new \InvalidArgumentException('Invalid isolation level:' . $level); @@ -1596,11 +1595,11 @@ abstract class AbstractPlatform * Gets the default transaction isolation level of the platform. * * @return integer The default isolation level. - * @see Doctrine\DBAL\Transaction constants. + * @see Doctrine\DBAL\Connection\TRANSACTION_* constants. */ public function getDefaultTransactionIsolationLevel() { - return Transaction::READ_COMMITTED; + return Connection::TRANSACTION_READ_COMMITTED; } /* supports*() metods */ @@ -1865,4 +1864,4 @@ abstract class AbstractPlatform { return 'TRUNCATE '.$tableName; } -} +} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 74593edf1..b391045c8 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -146,12 +146,12 @@ class OraclePlatform extends AbstractPlatform protected function _getTransactionIsolationLevelSQL($level) { switch ($level) { - case \Doctrine\DBAL\Transaction::READ_UNCOMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED: return 'READ UNCOMMITTED'; - case \Doctrine\DBAL\Transaction::READ_COMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED: return 'READ COMMITTED'; - case \Doctrine\DBAL\Transaction::REPEATABLE_READ: - case \Doctrine\DBAL\Transaction::SERIALIZABLE: + case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ: + case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE: return 'SERIALIZABLE'; default: return parent::_getTransactionIsolationLevelSQL($level); diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 022b819d0..a1c2184b9 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -130,11 +130,11 @@ class SqlitePlatform extends AbstractPlatform protected function _getTransactionIsolationLevelSQL($level) { switch ($level) { - case \Doctrine\DBAL\Transaction::READ_UNCOMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED: return 0; - case \Doctrine\DBAL\Transaction::READ_COMMITTED: - case \Doctrine\DBAL\Transaction::REPEATABLE_READ: - case \Doctrine\DBAL\Transaction::SERIALIZABLE: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ: + case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE: return 1; default: return parent::_getTransactionIsolationLevelSQL($level); diff --git a/lib/Doctrine/DBAL/Transaction.php b/lib/Doctrine/DBAL/Transaction.php deleted file mode 100644 index 3b29f3c79..000000000 --- a/lib/Doctrine/DBAL/Transaction.php +++ /dev/null @@ -1,229 +0,0 @@ -. - */ - -namespace Doctrine\DBAL; - -/** - * The Transaction class is the central access point to DBAL Transaction functionality. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - */ -class Transaction -{ - /** - * Constant for transaction isolation level READ UNCOMMITTED. - */ - const READ_UNCOMMITTED = 1; - - /** - * Constant for transaction isolation level READ COMMITTED. - */ - const READ_COMMITTED = 2; - - /** - * Constant for transaction isolation level REPEATABLE READ. - */ - const REPEATABLE_READ = 3; - - /** - * Constant for transaction isolation level SERIALIZABLE. - */ - const SERIALIZABLE = 4; - - /** - * The transaction nesting level. - * - * @var integer - */ - private $_transactionNestingLevel = 0; - - /** - * The currently active transaction isolation level. - * - * @var integer - */ - private $_transactionIsolationLevel; - - /** - * Flag that indicates whether the current transaction is marked for rollback only. - * - * @var boolean - */ - private $_isRollbackOnly = false; - - /** - * Constructor - * - * @param Connection $conn The DBAL Connection - */ - public function __construct(Connection $conn) - { - $this->_conn = $conn; - - $this->_transactionIsolationLevel = $conn->getDatabasePlatform()->getDefaultTransactionIsolationLevel(); - } - - /** - * Checks whether a transaction is currently active. - * - * @return boolean TRUE if a transaction is currently active, FALSE otherwise. - */ - public function isTransactionActive() - { - return $this->_transactionNestingLevel > 0; - } - - /** - * Sets the transaction isolation level. - * - * @param integer $level The level to set. - */ - public function setTransactionIsolation($level) - { - $this->_transactionIsolationLevel = $level; - - return $this->executeUpdate($this->_conn->getDatabasePlatform()->getSetTransactionIsolationSQL($level)); - } - - /** - * Gets the currently active transaction isolation level. - * - * @return integer The current transaction isolation level. - */ - public function getTransactionIsolation() - { - return $this->_transactionIsolationLevel; - } - - /** - * Returns the current transaction nesting level. - * - * @return integer The nesting level. A value of 0 means there's no active transaction. - */ - public function getTransactionNestingLevel() - { - return $this->_transactionNestingLevel; - } - - /** - * Starts a transaction by suspending auto-commit mode. - * - * @return void - */ - public function begin() - { - $conn = $this->_conn->getWrappedConnection(); - - if ($this->_transactionNestingLevel == 0) { - $conn->beginTransaction(); - } - - ++$this->_transactionNestingLevel; - } - - /** - * Commits the current transaction. - * - * @return void - * @throws ConnectionException If the commit failed due to no active transaction or - * because the transaction was marked for rollback only. - */ - public function commit() - { - if ($this->_transactionNestingLevel == 0) { - throw ConnectionException::commitFailedNoActiveTransaction(); - } - - if ($this->_isRollbackOnly) { - throw ConnectionException::commitFailedRollbackOnly(); - } - - $conn = $this->_conn->getWrappedConnection(); - - if ($this->_transactionNestingLevel == 1) { - $conn->commit(); - } - - --$this->_transactionNestingLevel; - } - - /** - * Cancel any database changes done during the current transaction. - * - * this method can be listened with onPreTransactionRollback and onTransactionRollback - * eventlistener methods - * - * @throws ConnectionException If the rollback operation failed. - */ - public function rollback() - { - if ($this->_transactionNestingLevel == 0) { - throw ConnectionException::rollbackFailedNoActiveTransaction(); - } - - if ($this->_transactionNestingLevel == 1) { - $this->_transactionNestingLevel = 0; - $this->_conn->getWrappedConnection()->rollback(); - $this->_isRollbackOnly = false; - } else { - $this->_isRollbackOnly = true; - --$this->_transactionNestingLevel; - } - } - - /** - * Marks the current transaction so that the only possible - * outcome for the transaction to be rolled back. - * - * @throws ConnectionException If no transaction is active. - */ - public function setRollbackOnly() - { - if ($this->_transactionNestingLevel == 0) { - throw ConnectionException::noActiveTransaction(); - } - - $this->_isRollbackOnly = true; - } - - /** - * Check whether the current transaction is marked for rollback only. - * - * @return boolean - * @throws ConnectionException If no transaction is active. - */ - public function getRollbackOnly() - { - if ($this->_transactionNestingLevel == 0) { - throw ConnectionException::noActiveTransaction(); - } - - return $this->_isRollbackOnly; - } -} \ No newline at end of file diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 843682ab0..a51c89e46 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -134,7 +134,7 @@ class EntityManager $config->getProxyDir(), $config->getProxyNamespace(), $config->getAutoGenerateProxyClasses()); - $this->_transaction = new EntityTransaction($conn->getTransaction()); + $this->_transaction = new EntityTransaction($this); } /** @@ -164,7 +164,7 @@ class EntityManager */ public function getTransaction() { - return $this->_transaction; + return $this->_transaction; } /** @@ -207,11 +207,12 @@ class EntityManager /** * Performs a rollback on the underlying database connection and closes the * EntityManager as it may now be in a corrupted state. + * + * @return boolean TRUE on success, FALSE on failure */ public function rollback() { - $this->getTransaction()->rollback(); - $this->close(); + return $this->getTransaction()->rollback(); } /** diff --git a/lib/Doctrine/ORM/EntityTransaction.php b/lib/Doctrine/ORM/EntityTransaction.php index 80695ee20..1257d0939 100644 --- a/lib/Doctrine/ORM/EntityTransaction.php +++ b/lib/Doctrine/ORM/EntityTransaction.php @@ -25,7 +25,6 @@ use Doctrine\DBAL\Transaction; /** * The Transaction class is the central access point to ORM Transaction functionality. - * This class acts more as a delegate class to the DBAL Transaction functionality. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.doctrine-project.org @@ -36,23 +35,31 @@ use Doctrine\DBAL\Transaction; * @author Jonathan Wage * @author Roman Borschel */ -class EntityTransaction +final class EntityTransaction { /** - * The wrapped DBAL Transaction. + * The wrapped ORM EntityManager. * - * @var Doctrine\DBAL\Transaction + * @var Doctrine\ORM\EntityManager */ - protected $_wrappedTransaction; + private $_em; + + /** + * The database connection used by the EntityManager. + * + * @var Doctrine\DBAL\Connection + */ + private $_conn; /** * Constructor. * * @param Transaction $transaction */ - public function __construct(Transaction $transaction) + public function __construct(EntityManager $em) { - $this->_wrappedTransaction = $transaction; + $this->_em = $em; + $this->_conn = $em->getConnection(); } /** @@ -62,7 +69,7 @@ class EntityTransaction */ public function isTransactionActive() { - return $this->_wrappedTransaction->isTransactionActive(); + return $this->_conn->isTransactionActive(); } /** @@ -72,7 +79,7 @@ class EntityTransaction */ public function setTransactionIsolation($level) { - return $this->_wrappedTransaction->setTransactionIsolation($level); + return $this->_conn->setTransactionIsolation($level); } /** @@ -82,7 +89,7 @@ class EntityTransaction */ public function getTransactionIsolation() { - return $this->_wrappedTransaction->getTransactionIsolation(); + return $this->_conn->getTransactionIsolation(); } /** @@ -92,7 +99,7 @@ class EntityTransaction */ public function getTransactionNestingLevel() { - return $this->_wrappedTransaction->getTransactionNestingLevel(); + return $this->_conn->getTransactionNestingLevel(); } /** @@ -102,7 +109,7 @@ class EntityTransaction */ public function begin() { - $this->_wrappedTransaction->begin(); + $this->_conn->beginTransaction(); } /** @@ -114,41 +121,43 @@ class EntityTransaction */ public function commit() { - $this->_wrappedTransaction->commit(); + $this->_conn->commit(); } /** * Cancel any database changes done during the current transaction. * * this method can be listened with onPreTransactionRollback and onTransactionRollback - * eventlistener methods + * event listener methods * + * @return boolean TRUE on success, FALSE on failure * @throws Doctrine\DBAL\ConnectionException If the rollback operation failed. */ public function rollback() { - $this->_wrappedTransaction->rollback(); + $this->_em->close(); + return $this->_conn->rollback(); } /** * Marks the current transaction so that the only possible * outcome for the transaction to be rolled back. * - * @throws ConnectionException If no transaction is active. + * @throws Doctrine\DBAL\ConnectionException If no transaction is active. */ public function setRollbackOnly() { - $this->_wrappedTransaction->setRollbackOnly(); + $this->_conn->setRollbackOnly(); } /** * Check whether the current transaction is marked for rollback only. * * @return boolean - * @throws ConnectionException If no transaction is active. + * @throws Doctrine\DBAL\ConnectionException If no transaction is active. */ - public function getRollbackOnly() + public function isRollbackOnly() { - return $this->_wrappedTransaction->getRollbackOnly(); + return $this->_conn->getRollbackOnly(); } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 95959ad38..63a99ea32 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -278,7 +278,7 @@ class UnitOfWork implements PropertyChangedListener $commitOrder = $this->_getCommitOrder(); $tx = $this->_em->getTransaction(); - + try { $tx->begin(); diff --git a/tests/Doctrine/Tests/DBAL/Functional/AllTests.php b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php index f5a0b0e9f..2132fe5b4 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/AllTests.php +++ b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php @@ -26,7 +26,7 @@ class AllTests $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\PostgreSqlSchemaManagerTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\OracleSchemaManagerTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\Schema\Db2SchemaManagerTest'); - $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\TransactionTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Functional\ConnectionTest'); return $suite; } diff --git a/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php new file mode 100644 index 000000000..fa6f23dce --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php @@ -0,0 +1,64 @@ +_conn->beginTransaction(); + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + + try { + $this->_conn->beginTransaction(); + $this->assertEquals(2, $this->_conn->getTransactionNestingLevel()); + throw new \Exception; + $this->_conn->commit(); // never reached + } catch (\Exception $e) { + $this->_conn->rollback(); + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + //no rethrow + } + $this->assertTrue($this->_conn->getRollbackOnly()); + + $this->_conn->commit(); // should throw exception + $this->fail('Transaction commit after failed nested transaction should fail.'); + } catch (ConnectionException $e) { + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + $this->_conn->rollback(); + $this->assertEquals(0, $this->_conn->getTransactionNestingLevel()); + } + } + + public function testTransactionBehavior() + { + try { + $this->_conn->beginTransaction(); + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + + throw new \Exception; + + $this->_connx->commit(); // never reached + } catch (\Exception $e) { + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + $this->_conn->rollback(); + $this->assertEquals(0, $this->_conn->getTransactionNestingLevel()); + } + + try { + $this->_conn->beginTransaction(); + $this->assertEquals(1, $this->_conn->getTransactionNestingLevel()); + $this->_conn->commit(); + } catch (\Exception $e) { + $this->_conn->rollback(); + $this->assertEquals(0, $this->_conn->getTransactionNestingLevel()); + } + } + +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/TransactionTest.php b/tests/Doctrine/Tests/DBAL/Functional/TransactionTest.php deleted file mode 100644 index 3663bbaaf..000000000 --- a/tests/Doctrine/Tests/DBAL/Functional/TransactionTest.php +++ /dev/null @@ -1,68 +0,0 @@ -_conn->getTransaction(); - - try { - $tx->begin(); - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - - try { - $tx->begin(); - $this->assertEquals(2, $tx->getTransactionNestingLevel()); - throw new \Exception; - $tx->commit(); // never reached - } catch (\Exception $e) { - $tx->rollback(); - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - //no rethrow - } - $this->assertTrue($tx->getRollbackOnly()); - - $tx->commit(); // should throw exception - $this->fail('Transaction commit after failed nested transaction should fail.'); - } catch (ConnectionException $e) { - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - $tx->rollback(); - $this->assertEquals(0, $tx->getTransactionNestingLevel()); - } - } - - public function testTransactionBehavior() - { - $tx = $this->_conn->getTransaction(); - - try { - $tx->begin(); - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - - throw new \Exception; - - $tx->commit(); // never reached - } catch (\Exception $e) { - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - $tx->rollback(); - $this->assertEquals(0, $tx->getTransactionNestingLevel()); - } - - try { - $tx->begin(); - $this->assertEquals(1, $tx->getTransactionNestingLevel()); - $tx->commit(); - } catch (\Exception $e) { - $tx->rollback(); - $this->assertEquals(0, $tx->getTransactionNestingLevel()); - } - } - -} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Platforms/MsSqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/MsSqlPlatformTest.php index e0691d74b..1302be035 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/MsSqlPlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/MsSqlPlatformTest.php @@ -44,19 +44,19 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase { $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_UNCOMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_COMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::REPEATABLE_READ) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::SERIALIZABLE) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) ); } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php index b2c916aec..8dbeac5db 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php @@ -53,20 +53,20 @@ class MySqlPlatformTest extends AbstractPlatformTestCase { $this->assertEquals( 'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_UNCOMMITTED), + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED), '' ); $this->assertEquals( 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_COMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) ); $this->assertEquals( 'SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::REPEATABLE_READ) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) ); $this->assertEquals( 'SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::SERIALIZABLE) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) ); } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php index c2b02d50f..8fb24abf6 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php @@ -55,19 +55,19 @@ class OraclePlatformTest extends AbstractPlatformTestCase { $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_UNCOMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_COMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::REPEATABLE_READ) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) ); $this->assertEquals( 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', - $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::SERIALIZABLE) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) ); } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php index 75a8aabe8..38681b3e1 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\DBAL\Platforms; use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Transaction; require_once __DIR__ . '/../../TestInit.php'; @@ -74,19 +73,19 @@ class PostgreSqlPlatformTest extends AbstractPlatformTestCase { $this->assertEquals( 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', - $this->_platform->getSetTransactionIsolationSQL(Transaction::READ_UNCOMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED) ); $this->assertEquals( 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED', - $this->_platform->getSetTransactionIsolationSQL(Transaction::READ_COMMITTED) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) ); $this->assertEquals( 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ', - $this->_platform->getSetTransactionIsolationSQL(Transaction::REPEATABLE_READ) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) ); $this->assertEquals( 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE', - $this->_platform->getSetTransactionIsolationSQL(Transaction::SERIALIZABLE) + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) ); } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php index 5a56b72bc..fae5538e3 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php @@ -36,10 +36,22 @@ class SqlitePlatformTest extends AbstractPlatformTestCase public function testGeneratesTransactionCommands() { - $this->assertEquals('PRAGMA read_uncommitted = 0', $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_UNCOMMITTED)); - $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::READ_COMMITTED)); - $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::REPEATABLE_READ)); - $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Transaction::SERIALIZABLE)); + $this->assertEquals( + 'PRAGMA read_uncommitted = 0', + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED) + ); + $this->assertEquals( + 'PRAGMA read_uncommitted = 1', + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) + ); + $this->assertEquals( + 'PRAGMA read_uncommitted = 1', + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) + ); + $this->assertEquals( + 'PRAGMA read_uncommitted = 1', + $this->_platform->getSetTransactionIsolationSQL(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) + ); } public function testPrefersIdentityColumns()