public function afterSave($event) { if (!$this->transaction) { return; } $this->transaction->commit(); $this->transaction = null; }
public static function rollbackStackedTransaction() { self::$transactionsStackSize && --self::$transactionsStackSize; //decrement only when positive if (self::$transactionsStackSize == 0) { self::$transaction->rollback(); } }
/** * Responds to {@link CActiveRecord::onAfterSave} event. * @throws CDbException * @param CModelEvent $event event parameter */ public function afterSave($event) { try { /** @var CDbCommandBuilder $commandBuilder */ $commandBuilder = $this->owner->dbConnection->commandBuilder; foreach ($this->owner->relations() as $name => $relation) { switch ($relation[0]) { /* MANY_MANY: this corresponds to the many-to-many relationship in database. * An associative table is needed to break a many-to-many relationship into one-to-many * relationships, as most DBMS do not support many-to-many relationship directly. */ case CActiveRecord::MANY_MANY: break; if (!is_array($this->owner->{$name})) { break; } Yii::trace('updating MANY_MANY table for relation ' . get_class($this->owner) . '.' . $name, 'system.db.ar.CActiveRecord'); // get table and fk information list($relationTable, $fks) = $this->parseManyManyFk($name, $relation); // get pks of the currently related records $newPKs = $this->getNewManyManyPks($name); // 1. delete relation table entries for records that have been removed from relation // @todo add support for composite primary keys $criteria = new CDbCriteria(); $criteria->addNotInCondition($fks[1], $newPKs)->addColumnCondition(array($fks[0] => $this->owner->getPrimaryKey())); $commandBuilder->createDeleteCommand($relationTable, $criteria)->execute(); // 2. add new entries to relation table // @todo add support for composite primary keys $oldPKs = $this->getOldManyManyPks($name); foreach ($newPKs as $fk) { if (!in_array($fk, $oldPKs)) { $commandBuilder->createInsertCommand($relationTable, array($fks[0] => $this->owner->getPrimaryKey(), $fks[1] => $fk))->execute(); } } // refresh relation data //$this->owner->getRelated($name, true); // will come back with github issue #4 break; // HAS_MANY: if the relationship between table A and B is one-to-many, then A has many B // (e.g. User has many Post); // HAS_ONE: this is special case of HAS_MANY where A has at most one B // (e.g. User has at most one Profile); // need to change the foreign ARs attributes // HAS_MANY: if the relationship between table A and B is one-to-many, then A has many B // (e.g. User has many Post); // HAS_ONE: this is special case of HAS_MANY where A has at most one B // (e.g. User has at most one Profile); // need to change the foreign ARs attributes case CActiveRecord::HAS_MANY: case CActiveRecord::HAS_ONE: if (!$this->owner->hasRelated($name) || !$this->isRelationSupported($relation)) { break; } Yii::trace('updating ' . ($relation[0] == CActiveRecord::HAS_ONE ? 'HAS_ONE' : 'HAS_MANY') . ' foreign-key field for relation ' . get_class($this->owner) . '.' . $name, 'system.db.ar.CActiveRecord'); $newRelatedRecords = $this->owner->getRelated($name, false); if ($relation[0] == CActiveRecord::HAS_MANY && !is_array($newRelatedRecords)) { if (!is_null($newRelatedRecords)) { throw new CDbException('A HAS_MANY relation needs to be an array of records or primary keys!'); } break; } // HAS_ONE is special case of HAS_MANY, so we have array with one or no element if ($relation[0] == CActiveRecord::HAS_ONE) { if ($newRelatedRecords === null) { $newRelatedRecords = array(); } else { $newRelatedRecords = array($newRelatedRecords); } } // get related records as objects and primary keys $newRelatedRecords = $this->primaryKeysToObjects($newRelatedRecords, $relation[1]); $newPKs = $this->objectsToPrimaryKeys($newRelatedRecords); // update all not anymore related records $criteria = new ECompositeDbCriteria(); $criteria->addNotInCondition(CActiveRecord::model($relation[1])->tableSchema->primaryKey, $newPKs); // @todo add support for composite primary keys $criteria->addColumnCondition(array($relation[2] => $this->owner->getPrimaryKey())); if (CActiveRecord::model($relation[1])->tableSchema->getColumn($relation[2])->allowNull) { CActiveRecord::model($relation[1])->updateAll(array($relation[2] => null), $criteria); } else { CActiveRecord::model($relation[1])->deleteAll($criteria); } /** @var CActiveRecord $record */ foreach ($newRelatedRecords as $record) { // only save if relation did not exist // @todo add support for composite primary keys if ($record->{$relation[2]} === null || $record->{$relation[2]} != $this->owner->getPrimaryKey()) { $record->saveAttributes(array($relation[2] => $this->owner->getPrimaryKey())); } } break; } } // commit internal transaction if one exists if ($this->_transaction !== null) { $this->_transaction->commit(); } } catch (Exception $e) { // roll back internal transaction if one exists if ($this->_transaction !== null) { $this->_transaction->rollback(); } // re-throw exception throw $e; } }
/** * Применение изменений. * @throws \CDbException */ private function commitTransaction() { if ($this->transaction !== null) { $this->transaction->commit(); } }
/** * Rollbacks changes applied with database. */ protected function rollbackChanges() { if ($this->_transaction->getActive()) { $this->_transaction->rollback(); } }
/** * Rolls back a database transaction if transaction is not `null`. * * @param \CDbTransaction $transaction */ protected function rollbackTransaction($transaction) { if ($transaction) { $transaction->rollback(); } }
public function rollBack() { if ($this->connection->decTransactionLevel() == 0) { parent::rollBack(); } }