Merge pull request #54 from dhensby/pulls/transaction-fixes

FIX Make sure nested transactions get reset on implicit commits
This commit is contained in:
Damian Mooyman 2018-06-28 10:56:18 +12:00 committed by GitHub
commit 34fb10580a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -475,22 +475,33 @@ class MSSQLDatabase extends Database
public function transactionRollback($savepoint = false) public function transactionRollback($savepoint = false)
{ {
// Named transaction
if ($savepoint) { if ($savepoint) {
$this->query("ROLLBACK TRANSACTION \"$savepoint\""); $this->query("ROLLBACK TRANSACTION \"$savepoint\"");
} else { return true;
--$this->transactionNesting;
if ($this->transactionNesting > 0) {
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
} elseif ($this->connector instanceof SQLServerConnector) {
$this->connector->transactionRollback();
} else {
$this->query('ROLLBACK TRANSACTION');
}
} }
// 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->query('ROLLBACK TRANSACTION');
}
return true;
} }
public function transactionEnd($chain = false) public function transactionEnd($chain = false)
{ {
// Fail if transaction isn't available
if (!$this->transactionNesting) {
return false;
}
--$this->transactionNesting; --$this->transactionNesting;
if ($this->transactionNesting <= 0) { if ($this->transactionNesting <= 0) {
$this->transactionNesting = 0; $this->transactionNesting = 0;
@ -500,6 +511,36 @@ class MSSQLDatabase extends Database
$this->query('COMMIT TRANSACTION'); $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) public function comparisonClause($field, $value, $exact = false, $negate = false, $caseSensitive = null, $parameterised = false)