Skip to content

Commit

Permalink
roll back to a given transaction level (savepoint). Dont fire event o…
Browse files Browse the repository at this point in the history
…n redundant rollBack()
  • Loading branch information
halaei committed Oct 12, 2016
1 parent 057492d commit 342578b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/Illuminate/Database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -639,19 +639,29 @@ public function commit()
/**
* Rollback the active database transaction.
*
* @param int|null $toLevel
* @return void
*/
public function rollBack()
public function rollBack($toLevel = null)
{
if ($this->transactions == 1) {
if (is_null($toLevel)) {
$toLevel = $this->transactions - 1;
}

if ($toLevel < 0 || $toLevel >= $this->transactions) {
// Ignore
return;
}

if ($toLevel == 0) {
$this->getPdo()->rollBack();
} elseif ($this->transactions > 1 && $this->queryGrammar->supportsSavepoints()) {
} elseif ($this->queryGrammar->supportsSavepoints()) {
$this->getPdo()->exec(
$this->queryGrammar->compileSavepointRollBack('trans'.$this->transactions)
$this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1))
);
}

$this->transactions = max(0, $this->transactions - 1);
$this->transactions = $toLevel;

$this->fireConnectionEvent('rollingBack');
}
Expand Down
11 changes: 11 additions & 0 deletions tests/Database/DatabaseConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,22 @@ public function testRollBackedFiresEventsIfSet()
$pdo = $this->createMock('DatabaseConnectionTestMockPDO');
$connection = $this->getMockConnection(['getName'], $pdo);
$connection->expects($this->any())->method('getName')->will($this->returnValue('name'));
$connection->beginTransaction();
$connection->setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher'));
$events->shouldReceive('fire')->once()->with(m::type('Illuminate\Database\Events\TransactionRolledBack'));
$connection->rollBack();
}

public function testRedundantRollBackFiresNoEvent()
{
$pdo = $this->createMock('DatabaseConnectionTestMockPDO');
$connection = $this->getMockConnection(['getName'], $pdo);
$connection->expects($this->any())->method('getName')->will($this->returnValue('name'));
$connection->setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher'));
$events->shouldNotReceive('fire');
$connection->rollBack();
}

public function testTransactionMethodRunsSuccessfully()
{
$pdo = $this->getMockBuilder('DatabaseConnectionTestMockPDO')->setMethods(['beginTransaction', 'commit'])->getMock();
Expand Down

0 comments on commit 342578b

Please sign in to comment.