Signatur
Beschreibung
Die MongoDB\Driver\Exception\ExecutionTimeoutException wird vom MongoDB-Treiber geworfen, wenn eine Datenbankoperation nicht innerhalb des konfigurierten Zeitlimits abgeschlossen werden kann. Dies kann beispielsweise passieren, wenn ein maxTimeMS-Limit für eine Abfrage oder einen Schreibvorgang gesetzt wurde und der Server dieses Limit überschreitet.
Diese Exception tritt serverseitig auf: Der MongoDB-Server bricht die Operation ab, sobald das definierte Zeitlimit erreicht ist, und gibt einen entsprechenden Fehlercode zurück. Der Treiber interpretiert diesen Fehlercode und wirft die ExecutionTimeoutException. Sie unterscheidet sich von Verbindungs-Timeouts, die durch MongoDB\Driver\Exception\ConnectionTimeoutException repräsentiert werden.
Typische Anwendungsfälle für das Setzen von Zeitlimits sind lang laufende Aggregationen, komplexe Abfragen oder Bulk-Operationen, bei denen sichergestellt werden soll, dass der Server nicht übermäßig viele Ressourcen verbraucht. Das Abfangen dieser Exception ermöglicht es, dem Benutzer eine aussagekräftige Fehlermeldung zu geben oder einen Fallback-Mechanismus zu aktivieren.
Die Klasse erbt von MongoDB\Driver\Exception\RuntimeException, welche wiederum von RuntimeException aus dem PHP-Kern erbt. Sie implementiert das Interface MongoDB\Driver\Exception\Exception.
Beispiele
maxTimeMS-Limit bei einer Abfrage setzen und Timeout abfangen
<?php
use MongoDB\Driver\Manager;
use MongoDB\Driver\Query;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Exception\ExecutionTimeoutException;
$manager = new Manager('mongodb://localhost:27017');
// Abfrage mit einem sehr kurzen maxTimeMS-Limit (1 Millisekunde)
$options = [
'maxTimeMS' => 1,
];
$query = new Query([], $options);
try {
$cursor = $manager->executeQuery(
'testdb.large_collection',
$query,
new ReadPreference(ReadPreference::PRIMARY)
);
$results = iterator_to_array($cursor);
echo 'Abfrage erfolgreich: ' . count($results) . ' Dokumente gefunden.';
} catch (ExecutionTimeoutException $e) {
echo 'Zeitüberschreitung bei der Abfrage: ' . $e->getMessage();
echo PHP_EOL . 'Fehlercode: ' . $e->getCode();
}
Timeout bei einem Aggregations-Command abfangen
<?php
use MongoDB\Driver\Manager;
use MongoDB\Driver\Command;
use MongoDB\Driver\Exception\ExecutionTimeoutException;
use MongoDB\Driver\Exception\RuntimeException;
$manager = new Manager('mongodb://localhost:27017');
$command = new Command([
'aggregate' => 'orders',
'pipeline' => [
['$group' => ['_id' => '$status', 'total' => ['$sum' => '$amount']]],
['$sort' => ['total' => -1]],
],
'cursor' => new stdClass(),
'maxTimeMS' => 5, // Sehr kurzes Zeitlimit für Demo-Zwecke
]);
try {
$cursor = $manager->executeCommand('testdb', $command);
foreach ($cursor as $result) {
echo $result->_id . ': ' . $result->total . PHP_EOL;
}
} catch (ExecutionTimeoutException $e) {
// Spezifisch auf Zeitüberschreitungen reagieren
echo 'Die Aggregation hat das Zeitlimit überschritten.' . PHP_EOL;
echo 'Details: ' . $e->getMessage() . PHP_EOL;
} catch (RuntimeException $e) {
// Andere Laufzeitfehler des Treibers
echo 'Allgemeiner Treiberfehler: ' . $e->getMessage() . PHP_EOL;
}
// Wichtig · Fallstricke
Serverseitiges vs. clientseitiges Timeout: Die ExecutionTimeoutException wird ausschließlich durch ein serverseitiges maxTimeMS-Limit ausgelöst (MongoDB-Fehlercode 50). Ein clientseitiges Verbindungs- oder Socket-Timeout führt zu einer MongoDB\Driver\Exception\ConnectionTimeoutException. Diese beiden Fälle sollten im Exception-Handling unterschieden werden.
Fehlercode: Der MongoDB-Fehlercode für Zeitüberschreitungen ist 50. Dieser kann über $e->getCode() abgerufen werden, um ihn programmatisch auszuwerten.
Produktionshinweis: Zu kleine maxTimeMS-Werte können zu häufigen Timeouts führen. Die Werte sollten sorgfältig auf Basis von Profiling-Daten gewählt und regelmäßig überprüft werden. Timeouts sollten geloggt werden, da sie auf fehlende Indizes oder ineffiziente Abfragen hindeuten können.