Commit ba2c35b8 by Qiang Xue

Fixes #2482.

parent 9f37e133
...@@ -377,7 +377,7 @@ class ActiveRecord extends BaseActiveRecord ...@@ -377,7 +377,7 @@ class ActiveRecord extends BaseActiveRecord
return false; return false;
} }
$db = static::getDb(); $db = static::getDb();
if ($this->isTransactional(self::OP_INSERT) && $db->getTransaction() === null) { if ($this->isTransactional(self::OP_INSERT)) {
$transaction = $db->beginTransaction(); $transaction = $db->beginTransaction();
try { try {
$result = $this->insertInternal($attributes); $result = $this->insertInternal($attributes);
...@@ -397,9 +397,12 @@ class ActiveRecord extends BaseActiveRecord ...@@ -397,9 +397,12 @@ class ActiveRecord extends BaseActiveRecord
} }
/** /**
* @see ActiveRecord::insert() * Inserts an ActiveRecord into DB without considering transaction.
* @param array $attributes list of attributes that need to be saved. Defaults to null,
* meaning all attributes that are loaded from DB will be saved.
* @return boolean whether the record is inserted successfully.
*/ */
private function insertInternal($attributes = null) protected function insertInternal($attributes = null)
{ {
if (!$this->beforeSave(true)) { if (!$this->beforeSave(true)) {
return false; return false;
...@@ -489,7 +492,7 @@ class ActiveRecord extends BaseActiveRecord ...@@ -489,7 +492,7 @@ class ActiveRecord extends BaseActiveRecord
return false; return false;
} }
$db = static::getDb(); $db = static::getDb();
if ($this->isTransactional(self::OP_UPDATE) && $db->getTransaction() === null) { if ($this->isTransactional(self::OP_UPDATE)) {
$transaction = $db->beginTransaction(); $transaction = $db->beginTransaction();
try { try {
$result = $this->updateInternal($attributes); $result = $this->updateInternal($attributes);
...@@ -530,36 +533,49 @@ class ActiveRecord extends BaseActiveRecord ...@@ -530,36 +533,49 @@ class ActiveRecord extends BaseActiveRecord
public function delete() public function delete()
{ {
$db = static::getDb(); $db = static::getDb();
$transaction = $this->isTransactional(self::OP_DELETE) && $db->getTransaction() === null ? $db->beginTransaction() : null; if ($this->isTransactional(self::OP_DELETE)) {
try { $transaction = $db->beginTransaction();
$result = false; try {
if ($this->beforeDelete()) { $result = $this->deleteInternal();
// we do not check the return value of deleteAll() because it's possible
// the record is already deleted in the database and thus the method will return 0
$condition = $this->getOldPrimaryKey(true);
$lock = $this->optimisticLock();
if ($lock !== null) {
$condition[$lock] = $this->$lock;
}
$result = $this->deleteAll($condition);
if ($lock !== null && !$result) {
throw new StaleObjectException('The object being deleted is outdated.');
}
$this->setOldAttributes(null);
$this->afterDelete();
}
if ($transaction !== null) {
if ($result === false) { if ($result === false) {
$transaction->rollBack(); $transaction->rollBack();
} else { } else {
$transaction->commit(); $transaction->commit();
} }
} } catch (\Exception $e) {
} catch (\Exception $e) {
if ($transaction !== null) {
$transaction->rollBack(); $transaction->rollBack();
throw $e;
}
} else {
$result = $this->deleteInternal();
}
return $result;
}
/**
* Deletes an ActiveRecord without considering transaction.
* @return integer|boolean the number of rows deleted, or false if the deletion is unsuccessful for some reason.
* Note that it is possible the number of rows deleted is 0, even though the deletion execution is successful.
* @throws StaleObjectException
*/
protected function deleteInternal()
{
$result = false;
if ($this->beforeDelete()) {
// we do not check the return value of deleteAll() because it's possible
// the record is already deleted in the database and thus the method will return 0
$condition = $this->getOldPrimaryKey(true);
$lock = $this->optimisticLock();
if ($lock !== null) {
$condition[$lock] = $this->$lock;
}
$result = $this->deleteAll($condition);
if ($lock !== null && !$result) {
throw new StaleObjectException('The object being deleted is outdated.');
} }
throw $e; $this->setOldAttributes(null);
$this->afterDelete();
} }
return $result; return $result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment