Index: branches/5.2.x/core/kernel/utility/temp_handler.php =================================================================== diff -u -N -r16733 -r16770 --- branches/5.2.x/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 16733) +++ branches/5.2.x/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 16770) @@ -1,6 +1,6 @@ 30) { - // another coping process failed to finished in 30 seconds + // Another coping process failed to finished in 30 seconds. $error_message = $this->Application->Phrase('la_error_TemporaryTableCopyingFailed'); $this->Application->SetVar('_temp_table_message', $error_message); + $log = $this->Application->log('Parallel item saving attempt detected'); + $log->addTrace(); + $log->setLogLevel(kLogger::LL_ERROR); + $log->write(); + return false; } - // mark, that we are coping from temp to live right now, so other similar attempt (from another script) will fail - $fields_hash = Array ( - 'SessionKey' => $this->Application->GetSID(), - 'Timestamp' => adodb_mktime(), - 'MainPrefix' => $this->Tables['Prefix'], - 'MainIDs' => implode(',', $master_ids), - ); + /* + * Mark, that we are coping from temp to live right now, + * so other similar attempt (from another script) will fail. + */ + $semaphore_id = $this->createSemaphore($conn, $master_ids); - $conn->doInsert($fields_hash, TABLE_PREFIX.'Semaphores'); - $semaphore_id = $conn->getInsertID(); - // unlock table now to prevent permanent lock in case, when coping will end with SQL error in the middle $conn->ChangeQuery('UNLOCK TABLES'); @@ -1023,6 +1023,33 @@ return $ids; } + /** + * Creates a semaphore. + * + * @param IDBConnection $conn Database connection. + * @param array $master_ids Master record IDs. + * + * @return integer + */ + protected function createSemaphore(IDBConnection $conn, array $master_ids) + { + $fields_hash = array( + 'SessionKey' => $this->Application->GetSID(), + 'Timestamp' => adodb_mktime(), + 'MainPrefix' => $this->Tables['Prefix'], + 'MainIDs' => implode(',', $master_ids), + 'UserId' => $this->Application->RecallVar('user_id'), + 'IPAddress' => $this->Application->getClientIp(), + 'Hostname' => $_SERVER['HTTP_HOST'], + 'RequestURI' => $_SERVER['REQUEST_URI'], + 'Backtrace' => serialize(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)), + ); + + $conn->doInsert($fields_hash, TABLE_PREFIX . 'Semaphores'); + + return $conn->getInsertID(); + } + function CancelEdit($master=null) { if (!isset($master)) $master = $this->Tables;