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
$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
if ($sClass != $sRootClass) {
$this->DBInsertSingleTable($sClass);
@@ -3206,6 +3210,7 @@ abstract class DBObject implements iDisplay
}
}
$this->SetReadWrite();
$this->m_bIsInDB = true;
$this->m_bDirty = false;
foreach ($this->m_aCurrValues as $sAttCode => $value) {
@@ -3215,9 +3220,6 @@ abstract class DBObject implements iDisplay
$this->m_aOrigValues[$sAttCode] = $value;
}
// Prevent DBUpdate at this point (reentrance protection)
MetaModel::StartReentranceProtection($this);
try {
$this->PostInsertActions();
}
@@ -3382,6 +3384,7 @@ abstract class DBObject implements iDisplay
}
}
$this->SetReadOnly('No modification allowed during transaction');
$iTransactionRetry = 1;
$bIsTransactionEnabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
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)
// 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
$this->SetReadWrite();
$this->m_bDirty = false;
$this->m_aTouchedAtt = array();
$this->m_aModifiedAtt = array();

View File

@@ -7567,6 +7567,20 @@ abstract class MetaModel
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
*