Browse Source

#1039: prevent concurrent executions of either synchro_import.php or synchro_exec.php for a given data source, since it would lead to unpredictable results.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3465 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 10 years ago
parent
commit
4a57214936
2 changed files with 13 additions and 4 deletions
  1. 6 3
      synchro/synchro_import.php
  2. 7 1
      synchro/synchrodatasource.class.inc.php

+ 6 - 3
synchro/synchro_import.php

@@ -468,8 +468,10 @@ try
 	   // Prepare insert columns
 		$sInsertColumns = '`'.implode('`, `', $aInputColumns).'`';
 	
-	   foreach($aData as $iRow => $aRow)
-	   {
+		$oMutex = new iTopMutex('synchro_import_'.$oDataSource->GetKey().'_'.$oConfig->GetDBName().'_'.$oConfig->GetDBSubname());
+		$oMutex->Lock();
+		foreach($aData as $iRow => $aRow)
+	  	{
 	      $sReconciliationCondition = "`primary_key` = ".CMDBSource::Quote($aRow[$iPrimaryKeyCol]);
 			$sSelect = "SELECT COUNT(*) FROM `$sTable` WHERE $sReconciliationCondition"; 
 			$aRes = CMDBSource::QueryToArray($sSelect);
@@ -597,7 +599,8 @@ try
 				$oP->add("$iRow: Error - Failed to reconcile, found $iCount rows having '$sReconciliationCondition'\n");
 			}
 		}
-	
+		$oMutex->Unlock();
+		
 		if (($sOutput == "summary") || ($sOutput == 'details'))
 		{
 			$oP->add_comment("Data Source: ".$iDataSourceId);

+ 7 - 1
synchro/synchrodatasource.class.inc.php

@@ -2414,10 +2414,14 @@ class SynchroExecution
 		$this->PrepareLogs();
 
 		self::$m_oCurrentTask = $this->m_oDataSource;
+
+		$oMutex = new iTopMutex('synchro_process_'.$this->m_oDataSource->GetKey().'_'.$oConfig->GetDBName().'_'.$oConfig->GetDBSubname());
 		try
 		{
+			$oMutex->Lock();
 			$this->DoSynchronize();
-
+			$oMutex->Unlock();
+				
 			$this->m_oStatLog->Set('end_date', time());
 			$this->m_oStatLog->Set('status', 'completed');
 			$this->m_oStatLog->DBUpdateTracked($this->m_oChange);
@@ -2459,6 +2463,7 @@ class SynchroExecution
 		}
 		catch (SynchroExceptionNotStarted $e)
 		{
+			$oMutex->Unlock();
 			// Set information for reporting... but delete the object in DB
 			$this->m_oStatLog->Set('end_date', time());
 			$this->m_oStatLog->Set('status', 'error');
@@ -2468,6 +2473,7 @@ class SynchroExecution
 		}
 		catch (Exception $e)
 		{
+			$oMutex->Unlock();
 			$this->m_oStatLog->Set('end_date', time());
 			$this->m_oStatLog->Set('status', 'error');
 			$this->m_oStatLog->Set('last_error', $e->getMessage());