5324-enhance CRUD to avoid collision/reentrance when using events on links

This commit is contained in:
odain
2023-09-01 15:33:11 +02:00
parent 6dc88c372b
commit 6d3f7f4976
2 changed files with 91 additions and 72 deletions

View File

@@ -3157,6 +3157,10 @@ abstract class DBObject implements iDisplay
// First query built upon on the root class, because the ID must be created first // First query built upon on the root class, because the ID must be created first
$this->m_iKey = $this->DBInsertSingleTable($sRootClass); $this->m_iKey = $this->DBInsertSingleTable($sRootClass);
//since N°5324: issue with test and db links events
$this->SetReadOnly('No modification allowed during transaction');
MetaModel::StartReentranceProtection($this);
// Then do the leaf class, if different from the root class // Then do the leaf class, if different from the root class
if ($sClass != $sRootClass) { if ($sClass != $sRootClass) {
$this->DBInsertSingleTable($sClass); $this->DBInsertSingleTable($sClass);
@@ -3206,6 +3210,7 @@ abstract class DBObject implements iDisplay
} }
} }
$this->SetReadWrite();
$this->m_bIsInDB = true; $this->m_bIsInDB = true;
$this->m_bDirty = false; $this->m_bDirty = false;
foreach ($this->m_aCurrValues as $sAttCode => $value) { foreach ($this->m_aCurrValues as $sAttCode => $value) {
@@ -3215,9 +3220,6 @@ abstract class DBObject implements iDisplay
$this->m_aOrigValues[$sAttCode] = $value; $this->m_aOrigValues[$sAttCode] = $value;
} }
// Prevent DBUpdate at this point (reentrance protection)
MetaModel::StartReentranceProtection($this);
try { try {
$this->PostInsertActions(); $this->PostInsertActions();
} }
@@ -3382,6 +3384,7 @@ abstract class DBObject implements iDisplay
} }
} }
$this->SetReadOnly('No modification allowed during transaction');
$iTransactionRetry = 1; $iTransactionRetry = 1;
$bIsTransactionEnabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled'); $bIsTransactionEnabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
if ($bIsTransactionEnabled) { if ($bIsTransactionEnabled) {
@@ -3496,6 +3499,8 @@ abstract class DBObject implements iDisplay
// following lines are resetting changes (so after this {@see DBObject::ListChanges()} won't return changes anymore) // following lines are resetting changes (so after this {@see DBObject::ListChanges()} won't return changes anymore)
// new values are already in the object (call {@see DBObject::Get()} to get them) // new values are already in the object (call {@see DBObject::Get()} to get them)
// call {@see DBObject::ListPreviousValuesForUpdatedAttributes()} to get changed fields and previous values // call {@see DBObject::ListPreviousValuesForUpdatedAttributes()} to get changed fields and previous values
$this->SetReadWrite();
$this->m_bDirty = false; $this->m_bDirty = false;
$this->m_aTouchedAtt = array(); $this->m_aTouchedAtt = array();
$this->m_aModifiedAtt = array(); $this->m_aModifiedAtt = array();

View File

@@ -7567,6 +7567,20 @@ abstract class MetaModel
return false; return false;
} }
/**
* @since 3.1.0 N°5324: to ease reentrance checks when using events on links (to avoid reentering if main link object ongoing operation)
*/
public static function GetReentranceObjectByChildClass(string $sParentClass, $sKey)
{
foreach (self::EnumChildClasses($sParentClass, ENUM_CHILD_CLASSES_ALL, false) as $sChildClass){
if (self::GetReentranceObject($sChildClass, $sKey)){
return true;
}
}
return false;
}
/** /**
* @param \DBObject $oObject * @param \DBObject $oObject
* *