Index: branches/5.2.x/units/orders/orders_config.php
===================================================================
--- branches/5.2.x/units/orders/orders_config.php
+++ branches/5.2.x/units/orders/orders_config.php
@@ -116,6 +116,16 @@
 							'DoSpecial' => '',
 							'DoEvent' => 'OnRestoreOrder',
 						),
+						array(
+							'Mode' => hAFTER,
+							'Conditional' => false,
+							'HookToPrefix' => 'conf',
+							'HookToSpecial' => '',
+							'HookToEvent' => array('OnBeforeItemValidate'),
+							'DoPrefix' => '',
+							'DoSpecial' => '',
+							'DoEvent' => 'OnBeforeNextOrderNumberChange',
+						),
 					),
 					'AggregateTags' => Array (
 							Array (
Index: branches/5.2.x/units/orders/orders_event_handler.php
===================================================================
--- branches/5.2.x/units/orders/orders_event_handler.php
+++ branches/5.2.x/units/orders/orders_event_handler.php
@@ -2272,21 +2272,18 @@
 	}
 
 	/**
-	 * Set next available order number
+	 * Set next available order number.
 	 *
-	 * @param kEvent $event
+	 * @param kEvent $event Event.
+	 *
+	 * @return void
 	 */
-	function setNextOrderNumber($event)
+	protected function setNextOrderNumber(kEvent $event)
 	{
+		/** @var OrdersItem $object */
 		$object = $event->getObject();
-		/* @var $object OrdersItem */
 
-		$sql = 'SELECT MAX(Number)
-				FROM ' . $this->Application->GetLiveName($object->TableName);
-		$next_order_number = $this->Conn->GetOne($sql) + 1;
-
-		$next_order_number = max($next_order_number, $this->Application->ConfigValue('Comm_Next_Order_Number'));
-		$this->Application->SetConfigValue('Comm_Next_Order_Number', $next_order_number + 1);
+		$next_order_number = $this->getNextOrderNumber();
 
 		$object->SetDBField('Number', $next_order_number);
 		$object->SetDBField('SubNumber', 0);
@@ -2300,6 +2297,63 @@
 	}
 
 	/**
+	 * Returns order number to be used next.
+	 *
+	 * @return integer
+	 */
+	protected function getNextOrderNumber()
+	{
+		$config_table = $this->Application->getUnitOption('conf', 'TableName');
+		$this->Conn->Query('LOCK TABLES ' . $config_table . ' WRITE');
+
+		$sql = 'UPDATE ' . $config_table . '
+				SET VariableValue = VariableValue + 1
+				WHERE VariableName = "Comm_Next_Order_Number"';
+		$this->Conn->Query($sql);
+
+		$sql = 'SELECT VariableValue
+				FROM ' . $config_table . '
+				WHERE VariableName = "Comm_Next_Order_Number"';
+		$next_order_number = $this->Conn->GetOne($sql);
+
+		$this->Conn->Query('UNLOCK TABLES');
+		$this->Application->SetConfigValue('Comm_Next_Order_Number', $next_order_number);
+
+		return $next_order_number - 1;
+	}
+
+	/**
+	 * [HOOK] Ensures, that "Next Order Number" system setting is within allowed limits.
+	 *
+	 * @param kEvent $event Event.
+	 *
+	 * @return void
+	 */
+	protected function OnBeforeNextOrderNumberChange(kEvent $event)
+	{
+		/** @var kDBItem $system_setting */
+		$system_setting = $event->MasterEvent->getObject();
+
+		$old_value = $system_setting->GetOriginalField('VariableValue');
+		$new_value = $system_setting->GetDBField('VariableValue');
+
+		if ( $system_setting->GetDBField('VariableName') != 'Comm_Next_Order_Number' || $new_value == $old_value ) {
+			return;
+		}
+
+		$sql = 'SELECT MAX(Number)
+				FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName');
+		$next_order_number = (int)$this->Conn->GetOne($sql) + 1;
+
+		if ( $new_value < $next_order_number ) {
+			$system_setting->SetError('VariableValue', 'value_out_of_range', null, array(
+				'min_value' => $next_order_number,
+				'max_value' => '&infin;',
+			));
+		}
+	}
+
+	/**
 	 * Set's new order address based on another address from order (e.g. billing from shipping)
 	 *
 	 * @param unknown_type $object