Index: branches/5.2.x/core/install/install_schema.sql =================================================================== --- branches/5.2.x/core/install/install_schema.sql +++ branches/5.2.x/core/install/install_schema.sql @@ -1277,6 +1277,7 @@ SessionKey int(10) unsigned NOT NULL DEFAULT '0', `Timestamp` int(10) unsigned NOT NULL DEFAULT '0', MainPrefix varchar(255) NOT NULL DEFAULT '', + MainIDs text, PRIMARY KEY (SemaphoreId), KEY SessionKey (SessionKey), KEY `Timestamp` (`Timestamp`), Index: branches/5.2.x/core/install/upgrades.sql =================================================================== --- branches/5.2.x/core/install/upgrades.sql +++ branches/5.2.x/core/install/upgrades.sql @@ -2934,3 +2934,4 @@ WHERE TemplateName LIKE 'USER%'; UPDATE SystemSettings SET VariableValue = 1 WHERE VariableName = 'CSVExportEncoding'; +ALTER TABLE Semaphores ADD MainIDs INT NULL DEFAULT NULL AFTER MainPrefix; Index: branches/5.2.x/core/kernel/utility/temp_handler.php =================================================================== --- branches/5.2.x/core/kernel/utility/temp_handler.php +++ branches/5.2.x/core/kernel/utility/temp_handler.php @@ -569,15 +569,7 @@ */ public function DoCopyTempToOriginal($master, $parent_prefix = null, $current_ids = Array()) { - if ( !$current_ids ) { - $query = 'SELECT ' . $master['IdField'] . ' FROM ' . $this->GetTempName($master['TableName']); - - if ( isset($master['Constrain']) ) { - $query .= ' WHERE ' . $master['Constrain']; - } - - $current_ids = $this->Conn->GetCol($query); - } + $current_ids = $this->getMainIDs($master, $current_ids); $table_sig = $master['TableName'] . (isset($master['Constrain']) ? $master['Constrain'] : ''); @@ -722,6 +714,30 @@ } /** + * Returns IDs from main temp table. + * + * @param array $master Master table configuration. + * @param array $current_ids User provided IDs. + * + * @return array + */ + protected function getMainIDs(array $master, array $current_ids = array()) + { + if ( $current_ids ) { + return $current_ids; + } + + $sql = 'SELECT ' . $master['IdField'] . ' + FROM ' . $this->GetTempName($master['TableName']); + + if ( isset($master['Constrain']) ) { + $sql .= ' WHERE ' . $master['Constrain']; + } + + return $this->Conn->GetCol($sql); + } + + /** * Create separate connection for locking purposes * * @return kDBConnection @@ -916,14 +932,26 @@ $conn =& $this->_getSeparateConnection(); $sleep_count = 0; + $master_ids = $this->getMainIDs($this->Tables, $master_ids); + do { // acquire lock $conn->ChangeQuery('LOCK TABLES '.TABLE_PREFIX.'Semaphores WRITE'); - $sql = 'SELECT SessionKey + $another_coping_active = false; + $sql = 'SELECT MainIDs FROM ' . TABLE_PREFIX . 'Semaphores - WHERE (MainPrefix = ' . $conn->qstr($this->Tables['Prefix']) . ')'; - $another_coping_active = $conn->GetOne($sql); + WHERE MainPrefix = ' . $conn->qstr($this->Tables['Prefix']) . ' AND MainIDs <> "0"'; + $other_semaphores_main_ids = $conn->GetCol($sql); + + foreach ( $other_semaphores_main_ids as $other_semaphore_main_ids ) { + $other_semaphore_main_ids = explode(',', $other_semaphore_main_ids); + + if ( array_intersect($master_ids, $other_semaphore_main_ids) ) { + $another_coping_active = true; + break; + } + } if ($another_coping_active) { // another user is coping data from temp table to live -> release lock and try again after 1 second @@ -946,6 +974,7 @@ 'SessionKey' => $this->Application->GetSID(), 'Timestamp' => adodb_mktime(), 'MainPrefix' => $this->Tables['Prefix'], + 'MainIDs' => implode(',', $master_ids), ); $conn->doInsert($fields_hash, TABLE_PREFIX.'Semaphores');