new record locking mechanism
This commit is contained in:
parent
a2111d60af
commit
ad44c65648
4 changed files with 60 additions and 63 deletions
|
@ -635,7 +635,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
|||
$record->delete($conn);
|
||||
}
|
||||
|
||||
Doctrine::debug(true);
|
||||
$conn->commit();
|
||||
|
||||
$this->data = array();
|
||||
|
|
|
@ -141,21 +141,52 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
|||
{
|
||||
$conn = $this->getConnection();
|
||||
|
||||
if ($conn->transaction->isSaved($record)) {
|
||||
$state = $record->state();
|
||||
if ($state === Doctrine_Record::STATE_LOCKED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$conn->transaction->addSaved($record);
|
||||
$record->state(Doctrine_Record::STATE_LOCKED);
|
||||
|
||||
$conn->beginTransaction();
|
||||
|
||||
$saveLater = $this->saveRelated($record);
|
||||
|
||||
$record->state($state);
|
||||
|
||||
if ($record->isValid()) {
|
||||
$this->save($record);
|
||||
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
|
||||
|
||||
$record->preSave($event);
|
||||
|
||||
$record->getTable()->getRecordListener()->preSave($event);
|
||||
|
||||
if ( ! $event->skipOperation) {
|
||||
switch ($state) {
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$this->insert($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
$this->update($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$record->getTable()->getRecordListener()->postSave($event);
|
||||
|
||||
$record->postSave($event);
|
||||
} else {
|
||||
$conn->transaction->addInvalid($record);
|
||||
}
|
||||
|
||||
$state = $record->state();
|
||||
|
||||
$record->state(Doctrine_Record::STATE_LOCKED);
|
||||
|
||||
foreach ($saveLater as $fk) {
|
||||
$alias = $fk->getAlias();
|
||||
|
@ -169,8 +200,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
|||
// save the MANY-TO-MANY associations
|
||||
$this->saveAssociations($record);
|
||||
|
||||
$record->state($state);
|
||||
|
||||
$conn->commit();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
|
@ -262,26 +295,25 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
|||
foreach ($record->getReferences() as $k => $v) {
|
||||
$rel = $record->getTable()->getRelation($k);
|
||||
|
||||
if ($rel instanceof Doctrine_Relation_ForeignKey ||
|
||||
$rel instanceof Doctrine_Relation_LocalKey) {
|
||||
$local = $rel->getLocal();
|
||||
$foreign = $rel->getForeign();
|
||||
$local = $rel->getLocal();
|
||||
$foreign = $rel->getForeign();
|
||||
|
||||
if ($record->getTable()->hasPrimaryKey($rel->getLocal())) {
|
||||
if ( ! $record->exists()) {
|
||||
$saveLater[$k] = $rel;
|
||||
} else {
|
||||
$v->save($this->conn);
|
||||
}
|
||||
if ($rel instanceof Doctrine_Relation_ForeignKey) {
|
||||
//if ( ! $record->exists()) {
|
||||
$saveLater[$k] = $rel;
|
||||
/**
|
||||
} else {
|
||||
// ONE-TO-ONE relationship
|
||||
$obj = $record->get($rel->getAlias());
|
||||
$v->save($this->conn);
|
||||
}
|
||||
*/
|
||||
} elseif ($rel instanceof Doctrine_Relation_LocalKey) {
|
||||
// ONE-TO-ONE relationship
|
||||
$obj = $record->get($rel->getAlias());
|
||||
|
||||
// Protection against infinite function recursion before attempting to save
|
||||
if ($obj instanceof Doctrine_Record &&
|
||||
$obj->isModified()) {
|
||||
$obj->save($this->conn);
|
||||
}
|
||||
// Protection against infinite function recursion before attempting to save
|
||||
if ($obj instanceof Doctrine_Record &&
|
||||
$obj->isModified()) {
|
||||
$obj->save($this->conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -319,11 +351,15 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
|||
|
||||
$this->conn->execute($query, array($r->getIncremented(), $record->getIncremented()));
|
||||
}
|
||||
|
||||
foreach ($v->getInsertDiff() as $r) {
|
||||
|
||||
|
||||
$assocRecord = $assocTable->create();
|
||||
$assocRecord->set($rel->getForeign(), $r);
|
||||
$assocRecord->set($rel->getLocal(), $record);
|
||||
$assocRecord->save($this->conn);
|
||||
|
||||
$this->saveGraph($assocRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1044,10 +1044,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
|||
if ($this->_data[$v] instanceof Doctrine_Record) {
|
||||
$this->_data[$v] = $this->_data[$v]->getIncremented();
|
||||
}
|
||||
|
||||
/** TODO:
|
||||
if ($this->_data[$v] === null) {
|
||||
throw new Doctrine_Record_Exception('Unexpected null value.');
|
||||
}
|
||||
*/
|
||||
|
||||
$a[$v] = $this->_data[$v];
|
||||
}
|
||||
|
|
|
@ -67,11 +67,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
|
|||
* @var array $_collections an array of Doctrine_Collection objects that were affected during the Transaction
|
||||
*/
|
||||
protected $_collections = array();
|
||||
/**
|
||||
* @var array $_saved an array of already saved records, this array is used for avoiding infinite loops in circular
|
||||
* saving operations
|
||||
*/
|
||||
protected $_saved = array();
|
||||
|
||||
/**
|
||||
* addCollection
|
||||
|
@ -90,38 +85,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* addSaved
|
||||
* adds a record into internal array of saved records
|
||||
*
|
||||
* at the end of each commit this array is emptied
|
||||
*
|
||||
* @param Doctrine_Record record to be added
|
||||
* @retrun Doctrine_Transaction this object
|
||||
*/
|
||||
public function addSaved(Doctrine_Record $record)
|
||||
{
|
||||
$this->_saved[] = $record;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* isSaved
|
||||
* returns whether or not given record is already saved
|
||||
*
|
||||
* this method is used for avoiding infinite loops within
|
||||
* cascading saves
|
||||
*
|
||||
* @param Doctrine_Record record to be checked
|
||||
* @return boolean whether or not given record is already saved
|
||||
*/
|
||||
public function isSaved(Doctrine_Record $record)
|
||||
{
|
||||
return in_array($record, $this->_saved, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* getState
|
||||
* returns the state of this connection
|
||||
|
@ -376,7 +339,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
|
|||
$coll->takeSnapshot();
|
||||
}
|
||||
$this->_collections = array();
|
||||
$this->_saved = array();
|
||||
$this->conn->getDbh()->commit();
|
||||
|
||||
//$this->conn->unitOfWork->reset();
|
||||
|
@ -442,7 +404,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
|
|||
throw new Doctrine_Transaction_Exception($e->getMessage());
|
||||
}
|
||||
}
|
||||
$this->_saved = array();
|
||||
|
||||
$listener->postTransactionRollback($event);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue