Skip to content

Commit

Permalink
Merge pull request #54 from dhensby/pulls/transaction-fixes
Browse files Browse the repository at this point in the history
FIX Make sure nested transactions get reset on implicit commits
  • Loading branch information
tractorcow authored Jun 27, 2018
2 parents 8b519f9 + 9d76e2a commit 34fb105
Showing 1 changed file with 49 additions and 8 deletions.
57 changes: 49 additions & 8 deletions code/MSSQLDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -475,22 +475,33 @@ public function transactionSavepoint($savepoint)

public function transactionRollback($savepoint = false)
{
// Named transaction
if ($savepoint) {
$this->query("ROLLBACK TRANSACTION \"$savepoint\"");
return true;
}

// Fail if transaction isn't available
if (!$this->transactionNesting) {
return false;
}
--$this->transactionNesting;
if ($this->transactionNesting > 0) {
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
} elseif ($this->connector instanceof SQLServerConnector) {
$this->connector->transactionRollback();
} else {
--$this->transactionNesting;
if ($this->transactionNesting > 0) {
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
} elseif ($this->connector instanceof SQLServerConnector) {
$this->connector->transactionRollback();
} else {
$this->query('ROLLBACK TRANSACTION');
}
$this->query('ROLLBACK TRANSACTION');
}
return true;
}

public function transactionEnd($chain = false)
{
// Fail if transaction isn't available
if (!$this->transactionNesting) {
return false;
}
--$this->transactionNesting;
if ($this->transactionNesting <= 0) {
$this->transactionNesting = 0;
Expand All @@ -500,6 +511,36 @@ public function transactionEnd($chain = false)
$this->query('COMMIT TRANSACTION');
}
}
return true;
}

/**
* In error condition, set transactionNesting to zero
*/
protected function resetTransactionNesting()
{
$this->transactionNesting = 0;
}

public function query($sql, $errorLevel = E_USER_ERROR)
{
$this->inspectQuery($sql);
return parent::query($sql, $errorLevel);
}

public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
{
$this->inspectQuery($sql);
return parent::preparedQuery($sql, $parameters, $errorLevel);
}

protected function inspectQuery($sql)
{
// Any DDL discards transactions.
$isDDL = $this->getConnector()->isQueryDDL($sql);
if ($isDDL) {
$this->resetTransactionNesting();
}
}

public function comparisonClause($field, $value, $exact = false, $negate = false, $caseSensitive = null, $parameterised = false)
Expand Down

0 comments on commit 34fb105

Please sign in to comment.