FIX Make sure nested transactions get reset on implicit commits

This commit is contained in:
Daniel Hensby 2018-06-20 12:33:47 +01:00 committed by Maxime Rainville
parent 6432ceea0d
commit 4167d9fd1a

View File

@ -485,25 +485,77 @@ class SQLite3Database extends Database
public function transactionRollback($savepoint = false) public function transactionRollback($savepoint = false)
{ {
// Named transaction
if ($savepoint) { if ($savepoint) {
$this->query("ROLLBACK TO $savepoint;"); $this->query("ROLLBACK TO $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);
} else { } else {
$this->query('ROLLBACK;'); $this->query('ROLLBACK;');
} }
return true;
} }
public function transactionDepth()
{
return $this->transactionNesting;
} }
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;
$this->query('COMMIT;'); $this->query('COMMIT;');
} }
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);
}
/**
* Inspect a SQL query prior to execution
*
* @param string $sql
*/
protected function inspectQuery($sql)
{
// Any DDL discards transactions.
$isDDL = $this->getConnector()->isQueryDDL($sql);
if ($isDDL) {
$this->resetTransactionNesting();
}
} }
public function clearTable($table) public function clearTable($table)