Added control abstractions for transaction demarcation.
This commit is contained in:
parent
e62b51cf38
commit
5dbd40563c
@ -19,7 +19,7 @@
|
||||
|
||||
namespace Doctrine\DBAL;
|
||||
|
||||
use PDO, Closure,
|
||||
use PDO, Closure, Exception,
|
||||
Doctrine\DBAL\Types\Type,
|
||||
Doctrine\DBAL\Driver\Connection as DriverConnection,
|
||||
Doctrine\Common\EventManager,
|
||||
@ -705,6 +705,28 @@ class Connection implements DriverConnection
|
||||
return $this->_conn->lastInsertId($seqName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a function in a transaction.
|
||||
*
|
||||
* The function gets passed this Connection instance as an (optional) parameter.
|
||||
*
|
||||
* If an exception occurs during execution of the function or transaction commit,
|
||||
* the transaction is rolled back and the exception re-thrown.
|
||||
*
|
||||
* @param Closure $func The function to execute transactionally.
|
||||
*/
|
||||
public function transactional(Closure $func)
|
||||
{
|
||||
$this->beginTransaction();
|
||||
try {
|
||||
$func($this);
|
||||
$this->commit();
|
||||
} catch (Exception $e) {
|
||||
$this->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transaction by suspending auto-commit mode.
|
||||
*
|
||||
|
@ -19,7 +19,8 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\Common\EventManager,
|
||||
use Closure, Exception,
|
||||
Doctrine\Common\EventManager,
|
||||
Doctrine\DBAL\Connection,
|
||||
Doctrine\ORM\Mapping\ClassMetadata,
|
||||
Doctrine\ORM\Mapping\ClassMetadataFactory,
|
||||
@ -176,6 +177,32 @@ class EntityManager
|
||||
$this->_conn->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a function in a transaction.
|
||||
*
|
||||
* The function gets passed this EntityManager instance as an (optional) parameter.
|
||||
*
|
||||
* {@link flush} is invoked prior to transaction commit.
|
||||
*
|
||||
* If an exception occurs during execution of the function or flushing or transaction commit,
|
||||
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
|
||||
*
|
||||
* @param Closure $func The function to execute transactionally.
|
||||
*/
|
||||
public function transactional(Closure $func)
|
||||
{
|
||||
$this->_conn->beginTransaction();
|
||||
try {
|
||||
$func($this);
|
||||
$this->flush();
|
||||
$this->_conn->commit();
|
||||
} catch (Exception $e) {
|
||||
$this->close();
|
||||
$this->_conn->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits a transaction on the underlying database connection.
|
||||
*
|
||||
|
@ -1290,6 +1290,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @return object The managed copy of the entity.
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
*
|
||||
* @todo Require active transaction!? OptimisticLockException may result in undefined state!?
|
||||
*/
|
||||
public function merge($entity)
|
||||
{
|
||||
|
@ -59,6 +59,16 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
|
||||
$this->_conn->rollback();
|
||||
$this->assertEquals(0, $this->_conn->getTransactionNestingLevel());
|
||||
}
|
||||
|
||||
$this->assertEquals(0, $this->_conn->getTransactionNestingLevel());
|
||||
try {
|
||||
$this->_conn->transactional(function($conn) {
|
||||
$conn->executeQuery("select 1");
|
||||
throw new \RuntimeException("Ooops!");
|
||||
});
|
||||
} catch (\RuntimeException $expected) {
|
||||
$this->assertEquals(0, $this->_conn->getTransactionNestingLevel());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -643,9 +643,10 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$address->zip = '12345';
|
||||
|
||||
$user->setAddress($address);
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->transactional(function($em) use($user) {
|
||||
$em->persist($user);
|
||||
});
|
||||
$this->_em->clear();
|
||||
|
||||
//$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
|
||||
@ -661,7 +662,6 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals('Germany', $address2->country);
|
||||
$this->assertEquals('Berlin', $address2->city);
|
||||
$this->assertEquals('12345', $address2->zip);
|
||||
|
||||
}
|
||||
|
||||
//DRAFT OF EXPECTED/DESIRED BEHAVIOR
|
||||
|
Loading…
x
Reference in New Issue
Block a user