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
$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());
// Protection against infinite function recursion before attempting to save
if ($obj instanceof Doctrine_Record &&
$obj->isModified()) {
$obj->save($this->conn);
}
$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);
}
}
}
......@@ -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);
}
......
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