Commit ad44c656 authored by zYne's avatar zYne

new record locking mechanism

parent a2111d60
...@@ -635,7 +635,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -635,7 +635,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$record->delete($conn); $record->delete($conn);
} }
Doctrine::debug(true);
$conn->commit(); $conn->commit();
$this->data = array(); $this->data = array();
......
...@@ -141,22 +141,53 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -141,22 +141,53 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
{ {
$conn = $this->getConnection(); $conn = $this->getConnection();
if ($conn->transaction->isSaved($record)) { $state = $record->state();
if ($state === Doctrine_Record::STATE_LOCKED) {
return false; return false;
} }
$conn->transaction->addSaved($record); $record->state(Doctrine_Record::STATE_LOCKED);
$conn->beginTransaction(); $conn->beginTransaction();
$saveLater = $this->saveRelated($record); $saveLater = $this->saveRelated($record);
$record->state($state);
if ($record->isValid()) { 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 { } else {
$conn->transaction->addInvalid($record); $conn->transaction->addInvalid($record);
} }
$state = $record->state();
$record->state(Doctrine_Record::STATE_LOCKED);
foreach ($saveLater as $fk) { foreach ($saveLater as $fk) {
$alias = $fk->getAlias(); $alias = $fk->getAlias();
...@@ -169,6 +200,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -169,6 +200,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
// save the MANY-TO-MANY associations // save the MANY-TO-MANY associations
$this->saveAssociations($record); $this->saveAssociations($record);
$record->state($state);
$conn->commit(); $conn->commit();
return true; return true;
...@@ -262,18 +295,18 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -262,18 +295,18 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
foreach ($record->getReferences() as $k => $v) { foreach ($record->getReferences() as $k => $v) {
$rel = $record->getTable()->getRelation($k); $rel = $record->getTable()->getRelation($k);
if ($rel instanceof Doctrine_Relation_ForeignKey ||
$rel instanceof Doctrine_Relation_LocalKey) {
$local = $rel->getLocal(); $local = $rel->getLocal();
$foreign = $rel->getForeign(); $foreign = $rel->getForeign();
if ($record->getTable()->hasPrimaryKey($rel->getLocal())) { if ($rel instanceof Doctrine_Relation_ForeignKey) {
if ( ! $record->exists()) { //if ( ! $record->exists()) {
$saveLater[$k] = $rel; $saveLater[$k] = $rel;
/**
} else { } else {
$v->save($this->conn); $v->save($this->conn);
} }
} else { */
} elseif ($rel instanceof Doctrine_Relation_LocalKey) {
// ONE-TO-ONE relationship // ONE-TO-ONE relationship
$obj = $record->get($rel->getAlias()); $obj = $record->get($rel->getAlias());
...@@ -284,7 +317,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -284,7 +317,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
} }
} }
}
return $saveLater; return $saveLater;
} }
...@@ -319,11 +351,15 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -319,11 +351,15 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$this->conn->execute($query, array($r->getIncremented(), $record->getIncremented())); $this->conn->execute($query, array($r->getIncremented(), $record->getIncremented()));
} }
foreach ($v->getInsertDiff() as $r) { foreach ($v->getInsertDiff() as $r) {
$assocRecord = $assocTable->create(); $assocRecord = $assocTable->create();
$assocRecord->set($rel->getForeign(), $r); $assocRecord->set($rel->getForeign(), $r);
$assocRecord->set($rel->getLocal(), $record); $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 ...@@ -1044,10 +1044,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
if ($this->_data[$v] instanceof Doctrine_Record) { if ($this->_data[$v] instanceof Doctrine_Record) {
$this->_data[$v] = $this->_data[$v]->getIncremented(); $this->_data[$v] = $this->_data[$v]->getIncremented();
} }
/** TODO:
if ($this->_data[$v] === null) { if ($this->_data[$v] === null) {
throw new Doctrine_Record_Exception('Unexpected null value.'); throw new Doctrine_Record_Exception('Unexpected null value.');
} }
*/
$a[$v] = $this->_data[$v]; $a[$v] = $this->_data[$v];
} }
......
...@@ -67,11 +67,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -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 * @var array $_collections an array of Doctrine_Collection objects that were affected during the Transaction
*/ */
protected $_collections = array(); 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 * addCollection
...@@ -90,38 +85,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -90,38 +85,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
return $this; 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 * getState
* returns the state of this connection * returns the state of this connection
...@@ -376,7 +339,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -376,7 +339,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
$coll->takeSnapshot(); $coll->takeSnapshot();
} }
$this->_collections = array(); $this->_collections = array();
$this->_saved = array();
$this->conn->getDbh()->commit(); $this->conn->getDbh()->commit();
//$this->conn->unitOfWork->reset(); //$this->conn->unitOfWork->reset();
...@@ -442,7 +404,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -442,7 +404,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
throw new Doctrine_Transaction_Exception($e->getMessage()); throw new Doctrine_Transaction_Exception($e->getMessage());
} }
} }
$this->_saved = array();
$listener->postTransactionRollback($event); $listener->postTransactionRollback($event);
} }
......
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