FIX Make sure nested transactions get reset on implicit commits

This commit is contained in:
Daniel Hensby 2018-06-20 12:49:08 +01:00
parent 8b519f9bcf
commit 9d76e2a042
No known key found for this signature in database
GPG Key ID: D8DEBC4C8E7BC8B9

View File

@ -475,9 +475,16 @@ 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;
}
// Fail if transaction isn't available
if (!$this->transactionNesting) {
return false;
}
--$this->transactionNesting; --$this->transactionNesting;
if ($this->transactionNesting > 0) { if ($this->transactionNesting > 0) {
$this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting); $this->transactionRollback('NESTEDTRANSACTION' . $this->transactionNesting);
@ -486,11 +493,15 @@ class MSSQLDatabase extends Database
} else { } else {
$this->query('ROLLBACK TRANSACTION'); $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)