Exécution d'opérations CRUD dans Amazon DocumentDB avec Java - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Exécution d'opérations CRUD dans Amazon DocumentDB avec Java

Cette section décrit l'exécution de l'opération CRUD (création, lecture, mise à jour, suppression) dans Amazon DocumentDB à l'aide des pilotes Java MongoDB.

Création et insertion de documents dans une collection DocumentDB

L'insertion de documents dans Amazon DocumentDB vous permet d'ajouter de nouvelles données à vos collections. Il existe plusieurs méthodes pour effectuer des insertions, en fonction de vos besoins et du volume de données avec lequel vous travaillez. La méthode la plus simple pour insérer un document individuel dans la collection estinsertOne(). Pour insérer plusieurs documents à la fois, vous pouvez utiliser insertMany() cette méthode, qui vous permet d'ajouter un ensemble de documents en une seule opération. Une autre méthode pour insérer de nombreux documents dans une collection DocumentDB est. bulkWrite() Dans ce guide, nous abordons toutes ces méthodes de création de documents dans une collection DocumentDB.

insertOne()

Commençons par examiner comment insérer un document individuel dans une collection Amazon DocumentDBB. L'insertion d'un seul document est réalisée à l'aide du insertOne() procédé. Cette méthode prend un BsonDocumentfor pour l'insertion et renvoie un InsertOneResultobjet qui peut être utilisé pour obtenir l'identifiant du nouveau document inséré. L'exemple de code ci-dessous montre l'insertion d'un document de restaurant dans la collection :

Document article = new Document() .append("restaurantId", "REST-21G145") .append("name", "Future-proofed Intelligent Bronze Hat") .append("cuisine", "International") .append("rating", new Document() .append("average", 1.8) .append("totalReviews", 267)) .append("features", Arrays.asList("Outdoor Seating", "Live Music")); try { InsertOneResult result = collection.insertOne(article); System.out.println("Inserted document with the following id: " + result.getInsertedId()); } catch (MongoWriteException e) { // Handle duplicate key or other write errors System.err.println("Failed to insert document: " + e.getMessage()); throw e; } catch (MongoException e) { // Handle other MongoDB errors System.err.println("MongoDB error: " + e.getMessage()); throw e; }

Lors de l'utilisationinsertOne(), veillez à inclure une gestion des erreurs appropriée. Par exemple, dans le code ci-dessus, « restaurantId » possède un index unique et, par conséquent, une nouvelle exécution de ce code générera les éléments suivants MongoWriteException :

Failed to insert document: Write operation error on server docdbCluster.docdb.amazonaws.com:27017. Write error: WriteError{code=11000, message='E11000 duplicate key error collection: Restaurants index: restaurantId_1', details={}}.

Insérer plusieurs ()

Les principales méthodes utilisées pour insérer de nombreux documents dans une collection sont insertMany () et. bulkWrite()

insertMany()Cette méthode est la plus simple pour insérer plusieurs documents en une seule opération. Il accepte une liste de documents et les insère dans la collection. Cette méthode est idéale lorsque vous insérez un lot de nouveaux documents indépendants les uns des autres et ne nécessitant aucun traitement spécial ni aucune opération mixte. Le code suivant montre la lecture de documents JSON à partir d'un fichier et leur insertion dans la collection. La insertMany() fonction renvoie un InsertManyResultInsertManyResultobjet qui peut être utilisé pour obtenir tous IDs les documents insérés.

// Read JSON file content String content = new String(Files.readAllBytes(Paths.get(jsonFileName))); JSONArray jsonArray = new JSONArray(content); // Convert JSON articles to Documents List < Document > restaurants = new ArrayList < > (); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); Document doc = Document.parse(jsonObject.toString()); restaurants.add(doc); } //insert documents in collection InsertManyResult result = collection.insertMany(restaurants); System.out.println("Count of inserted documents: " + result.getInsertedIds().size());

bulkWrite()

La bulkWrite() méthode permet d'effectuer plusieurs opérations d'écriture (insertion, mise à jour, suppression) en un seul lot. Vous pouvez l'utiliser bulkWrite() lorsque vous devez effectuer différents types d'opérations en un seul lot, comme l'insertion de certains documents tout en mettant à jour d'autres. bulkWrite()supporte deux types d'écriture par lots, ordonnée et non ordonnée :

  • Opérations ordonnées — (par défaut) Amazon DocumentDB traite les opérations d'écriture de manière séquentielle et s'arrête à la première erreur rencontrée. Cela est utile lorsque l'ordre des opérations est important, par exemple lorsque les opérations ultérieures dépendent des opérations précédentes. Cependant, les opérations ordonnées sont généralement plus lentes que les opérations non ordonnées. Dans le cas des opérations ordonnées, vous devez résoudre le cas où le lot s'arrête à la première erreur, ce qui peut laisser certaines opérations non traitées.

  • Opérations non ordonnées — Permet à Amazon DocumentDB de traiter les insertions en une seule exécution dans la base de données. Si une erreur se produit avec un document, l'opération se poursuit avec les autres documents. Cela est particulièrement utile lorsque vous insérez de grandes quantités de données et que vous pouvez tolérer certaines défaillances, par exemple lors de la migration de données ou d'importations en masse, lorsque certains documents peuvent échouer en raison de clés dupliquées. Dans le cas d'opérations non ordonnées, vous devez faire face à des scénarios de réussite partielle dans lesquels certaines opérations réussissent tandis que d'autres échouent.

Lorsque vous travaillez avec la bulkWrite() méthode, certaines classes essentielles sont requises. Tout d'abord, la WriteModelclasse sert de classe de base pour toutes les opérations d'écriture et avec des implémentations spécifiques telles que InsertOneModel, UpdateOneModel, UpdateManyModelDeleteOneModel, et pour la DeleteManyModelgestion de différents types d'opérations.

La BulkWriteOptionsclasse est nécessaire pour configurer le comportement des opérations en masse, telles que la définition de ordered/unordered l'exécution ou le contournement de la validation des documents. La BulkWriteResultclasse fournit des informations détaillées sur les résultats de l'exécution, y compris le nombre de documents insérés, mis à jour et supprimés.

Pour la gestion des erreurs, la MongoBulkWriteExceptionclasse est cruciale car elle contient des informations sur les défaillances survenant lors d'une opération en masse, tandis que la BulkWriteErrorclasse fournit des détails spécifiques sur les échecs d'opération individuels. Le code suivant montre un exemple d'insertion d'une liste de documents, ainsi que de mise à jour et de suppression d'un seul document, le tout dans le cadre de l'exécution d'un appel de bulkWrite() méthode unique. Le code indique également comment utiliser BulkWriteOptionset BulkWriteResult, ainsi que la gestion appropriée des erreurs lors de l'bulkWrite()opération.

List < WriteModel < Document >> bulkOperations = new ArrayList < > (); // get list of 10 documents representing 10 restaurants List < Document > restaurantsToInsert = getSampleData(); for (Document doc: restaurantsToInsert) { bulkOperations.add(new InsertOneModel < > (doc)); } // Update operation bulkOperations.add(new UpdateOneModel < > ( new Document("restaurantId", "REST-Y2E9H5"), new Document("", new Document("stats.likes", 20)) .append("", new Document("rating.average", 4.5)))); // Delete operation bulkOperations.add(new DeleteOneModel < > (new Document("restaurantId", "REST-D2L431"))); // Perform bulkWrite operation try { BulkWriteOptions options = new BulkWriteOptions() .ordered(false); // Allow unordered inserts BulkWriteResult result = collection.bulkWrite(bulkOperations, options); System.out.println("Inserted: " + result.getInsertedCount()); System.out.println("Updated: " + result.getModifiedCount()); System.out.println("Deleted: " + result.getDeletedCount()); } catch (MongoBulkWriteException e) { System.err.println("Bulk write error occurred: " + e.getMessage()); // Log individual write errors for (BulkWriteError error: e.getWriteErrors()) { System.err.printf("Error at index %d: %s (Code: %d)%n", error.getIndex(), error.getMessage(), error.getCode()); // Log the problematic document Document errorDoc = new Document(error.getDetails()); if (errorDoc != null) { System.err.println("Problematic document: " + errorDoc); } } } catch (Exception e) { System.err.println("Error during bulkWrite: " + e.getMessage()); }

écritures réessayables

Contrairement à MongoDB, Amazon DocumentDB ne prend pas en charge les écritures réessayables. Par conséquent, vous devez implémenter une logique de nouvelle tentative personnalisée dans leurs applications, en particulier pour gérer les problèmes de réseau ou l'indisponibilité temporaire des services. Une stratégie de nouvelle tentative bien mise en œuvre implique généralement d'augmenter le délai entre les tentatives et de limiter le nombre total de tentatives. Gestion des erreurs avec la logique de nouvelle tentativeVous trouverez ci-dessous un exemple de code expliquant comment créer une logique de nouvelle tentative avec gestion des erreurs.

Lire et récupérer des données d'une collection DocumentDB

L'interrogation de documents dans Amazon DocumentDB s'articule autour de plusieurs composants clés qui vous permettent de récupérer et de manipuler des données avec précision. La find()méthode est la requête fondamentale APIs dans les pilotes Java MongoDB. Il permet une extraction de données complexe avec de nombreuses options de filtrage, de tri et de projection des résultats. Outre la find() méthode, il FiltersFindIterableexiste deux autres composants fondamentaux qui fournissent les éléments de base pour les opérations de requête dans les pilotes Java MongoDB.

La Filters classe est une classe utilitaire du pilote Java MongoDB qui fournit une API fluide pour créer des filtres de requêtes. Cette classe propose des méthodes d'usine statiques qui créent des instances d'Bsonobjets représentant diverses conditions de requête. Les méthodes les plus couramment utilisées incluent eq() les comparaisons d'égalitégt(),lt(),gte(),, et lte() les comparaisons numériques, and() la combinaison or() de plusieurs conditions, in() les tests d'appartenance à des tableaux et la correspondance regex() de modèles. nin() La classe est conçue pour être sûre et fournit une meilleure vérification au moment de la compilation par rapport aux requêtes basées sur des documents bruts, ce qui en fait l'approche préférée pour créer des requêtes DocumentDB dans les applications Java. La gestion des erreurs est robuste, avec des exceptions claires émises pour les constructions de filtres non valides.

FindIterableest une interface spécialisée conçue pour gérer le résultat de la find() méthode. Il fournit un ensemble complet de méthodes pour affiner et contrôler l'exécution des requêtes, ainsi qu'une API fluide pour le chaînage des méthodes. L'interface inclut des méthodes essentielles de modification des requêtes, telles que limit() la restriction du nombre de documents renvoyés, skip() la pagination, le classement sort() des résultats, projection() la sélection de champs spécifiques et la sélection hint() d'index. Les opérations de traitement par lots, de sauts et de limites FindIterable sont des outils essentiels de pagination et de gestion des données qui permettent de contrôler la manière dont les documents sont extraits et traités à partir de la base de données.

Batching (batchSize) contrôle le nombre de documents que DocumentDB renvoie au client en un seul aller-retour sur le réseau. Lorsque vous définissez une taille de lot, DocumentDB ne renvoie pas tous les documents correspondants en une seule fois, mais les renvoie par groupes de la taille de lot spécifiée.

Skip vous permet de décaler le point de départ de vos résultats, en demandant essentiellement à DocumentDB de sauter un certain nombre de documents avant de commencer à renvoyer des correspondances. Par exemple, skip(20) contournera les 20 premiers documents correspondants. Ceci est couramment utilisé dans les scénarios de pagination où vous souhaitez récupérer les pages de résultats suivantes.

La limite limite le nombre total de documents pouvant être renvoyés par une requête. Lorsque vous le spécifiezlimit(n), DocumentDB arrête de renvoyer des documents après avoir renvoyé « n » documents, même s'il existe d'autres correspondances dans la base de données.

FindIterableprend en charge les modèles d'itérateur et de curseur lors de la récupération de documents depuis Amazon DocumentDB. L'avantage de l'utilisation FindIterable d'un itérateur est qu'il permet le chargement différé des documents et qu'il ne récupère les documents que lorsque l'application le demande. Un autre avantage de l'utilisation de l'itérateur est que vous n'êtes pas responsable du maintien de la connexion au cluster et qu'aucune fermeture explicite de la connexion n'est donc requise.

FindIterablefournissent également un support MongoCursorpermettant d'utiliser des modèles de curseur lors de l'utilisation de requêtes Amazon DocumentDB. MongoCursorest une implémentation spécifique au pilote Java MongoDB qui permet de contrôler les opérations de base de données et la gestion des ressources. Il implémente l'AutoCloseableinterface, permettant une gestion explicite des ressources par le biais de try-with-resources blocs, ce qui est crucial pour fermer correctement les connexions aux bases de données et libérer les ressources du serveur. Par défaut, le curseur expire au bout de 10 minutes et DocumentDB ne vous permet pas de modifier ce comportement de temporisation. Lorsque vous travaillez avec des données groupées, assurez-vous de récupérer le lot de données suivant avant que le curseur n'expire. L'une des principales considérations à prendre en compte lors de son utilisation MongoCursor est qu'elle nécessite une fermeture explicite pour éviter les fuites de ressources.

Dans cette section, plusieurs exemples sont présentés pourfind(), Filters etFindIterable.

L'exemple de code suivant montre comment récupérer un seul document find() à l'aide de son champ « RestaurantID » :

Document filter = new Document("restaurantId", "REST-21G145"); Document result = collection.find(filter).first();

Même si son utilisation Filters permet de mieux vérifier les erreurs lors de la compilation, le pilote Java vous permet également de spécifier un Bson filtre directement dans la find() méthode. L'exemple de code suivant transmet Bson le document à find() :

result = collection.find(new Document("$and", Arrays.asList( new Document("rating.totalReviews", new Document("$gt", 1000)), new Document("priceRange", "$$"))))

L'exemple de code suivant montre plusieurs exemples d'utilisation de la Filters classe avec find() :

FindIterable < Document > results; // Exact match results = collection.find(Filters.eq("name", "Thai Curry Palace")); // Not equal results = collection.find(Filters.ne("cuisine", "Thai")); // find an element in an array results = collection.find(Filters.in("features", Arrays.asList("Private Dining"))); // Greater than results = collection.find(Filters.gt("rating.average", 3.5)); // Between (inclusive) results = collection.find(Filters.and( Filters.gte("rating.totalReviews", 100), Filters.lte("rating.totalReviews", 200))); // AND results = collection.find(Filters.and( Filters.eq("cuisine", "Thai"), Filters.gt("rating.average", 4.5))); // OR results = collection.find(Filters.or( Filters.eq("cuisine", "Thai"), Filters.eq("cuisine", "American"))); // All document where the Field exists results = collection.find(Filters.exists("michelin")); // Regex results = collection.find(Filters.regex("name", Pattern.compile("Curry", Pattern.CASE_INSENSITIVE))); // Find all document where the array contain the list of value regardless of its order results = collection.find(Filters.all("features", Arrays.asList("Private Dining", "Parking"))); // Array size results = collection.find(Filters.size("features", 4));

L'exemple suivant montre comment enchaîner les opérations de sort()skip(),limit(), et batchSize() sur un FindIterable objet. L'ordre dans lequel ces opérations sont effectuées influencera les performances de votre requête. À titre de bonne pratique, l'ordre de ces opérations doit être sort()projection(),skip(), limit() etbatchSize().

FindIterable < Document > results = collection.find(Filters.gt("rating.totalReviews", 1000)) // Sorting .sort(Sorts.orderBy( Sorts.descending("address.city"), Sorts.ascending("cuisine"))) // Field selection .projection(Projections.fields( Projections.include("name", "cuisine", "priceRange"), Projections.excludeId())) // Pagination .skip(20) .limit(10) .batchSize(2);

L'exemple de code suivant montre la création d'un itérateur surFindIterable. Il utilise la forEach construction de Java pour parcourir le jeu de résultats.

collection.find(Filters.eq("cuisine", "American")).forEach(doc -> System.out.println(doc.toJson()));

Dans le dernier exemple de find() code, il montre comment l'utiliser cursor() pour récupérer des documents. Il crée le curseur dans le bloc d'essai, ce qui garantit que le curseur se ferme lorsque le code quitte le bloc d'essai.

try (MongoCursor < Document > cursor = collection.find(Filters.eq("cuisine", "American")) .batchSize(25) .cursor()) { while (cursor.hasNext()) { Document doc = cursor.next(); System.out.println(doc.toJson()); } } // Cursor automatically closed

Mettre à jour des documents existants dans une collection DocumentDB

Amazon DocumentDB fournit des mécanismes flexibles et puissants pour modifier des documents existants et en insérer de nouveaux lorsqu'ils n'existent pas. Le pilote Java MongoDB propose plusieurs méthodes de mise à jour : updateOne() pour les mises à jour d'un seul document, updateMany() pour les mises à jour de plusieurs documents et replaceOne() pour le remplacement complet du document. Outre ces trois méthodes, UpdatesUpdateOptions, et d'autres composants fondamentaux fournissent UpdateResultles éléments de base pour les opérations de mise à jour dans les pilotes Java MongoDB.

La Updates classe du pilote Java MongoDB est une classe utilitaire qui fournit des méthodes d'usine statiques pour créer des opérateurs de mise à jour. Il sert de générateur principal pour créer des opérations de mise à jour d'une manière sûre et lisible. Des méthodes de base telles que set()unset(), et inc() permettent de modifier directement les documents. La puissance de cette classe devient évidente lorsque vous combinez plusieurs opérations à l'aide de la Updates.combine() méthode qui permet d'exécuter plusieurs opérations de mise à jour de manière atomique, garantissant ainsi la cohérence des données.

UpdateOptionsest une puissante classe de configuration du pilote Java de MongoDB qui fournit des fonctionnalités de personnalisation essentielles pour les opérations de mise à jour de documents. Deux aspects importants de cette classe sont la prise en charge des filtres upsert et matriciels pour les opérations de mise à jour. La fonction Upsert, activée viaupsert(true), permet de créer de nouveaux documents lorsqu'aucun document correspondant n'est trouvé lors d'une opération de mise à jour. AinsiarrayFilters(), l'opération de mise à jour peut mettre à jour avec précision les éléments du tableau qui répondent à des critères spécifiques.

UpdateResultdans le pilote Java de MongoDB, fournit le mécanisme de feedback détaillant le résultat d'une opération de mise à jour. Cette classe encapsule trois indicateurs clés : le nombre de documents correspondant aux critères de mise à jour (matchedCount), le nombre de documents réellement modifiés (modifiedCount) et les informations relatives à tout document modifié (). upsertedId Il est essentiel de comprendre ces métriques pour gérer correctement les erreurs, vérifier les opérations de mise à jour et maintenir la cohérence des données dans les applications.

Mettre à jour et remplacer un seul document

Dans DocumentDB, la mise à jour d'un seul document peut être effectuée à l'aide de la méthode updateOne (). Cette méthode utilise un paramètre de filtre, généralement fourni par la Filters classe, pour identifier le document à mettre à jour, un paramètre Updat e qui détermine le ou les champs à mettre à jour et un UpdateOptions paramètre facultatif pour définir différentes options pour la mise à jour. L'utilisation de updateOne() cette méthode ne mettra à jour que le premier document correspondant aux critères de sélection. L'exemple de code suivant met à jour un seul champ d'un document :

collection.updateOne(Filters.eq("restaurantId", "REST-Y2E9H5"), Updates.set("name", "Amazing Japanese sushi"));

Pour mettre à jour plusieurs champs dans un document, utilisez updateOne() avec Update.combine() comme indiqué dans l'exemple suivant. Cet exemple montre également comment ajouter un élément à un tableau du document.

List<Bson> updates = new ArrayList<>(); // Basic field updates updates.add(Updates.set("name", "Shanghai Best")); // Array operations updates.add(Updates.addEachToSet("features", Arrays.asList("Live Music"))); // Counter updates updates.add(Updates.inc("rating.totalReviews", 10)); // Combine all updates Bson combinedUpdates = Updates.combine(updates); // Execute automic update with one call collection.updateOne(Filters.eq("restaurantId","REST-1J83NH"), combinedUpdates);

L'exemple de code suivant montre comment mettre à jour un document dans la base de données. Si le document spécifié n'existe pas, l'opération l'insère automatiquement en tant que nouveau document. Ce code montre également comment utiliser les métriques disponibles via l'UpdateResultobjet.

Bson filter = Filters.eq("restaurantId", "REST-0Y9GL0"); Bson update = Updates.set("cuisine", "Indian"); // Upsert operation UpdateOptions options = new UpdateOptions().upsert(true); UpdateResult result = collection.updateOne(filter, update, options); if (result.getUpsertedId() != null) { System.out.println("Inserted document with _id: " + result.getUpsertedId()); } else { System.out.println("Updated " + result.getModifiedCount() + " document(s)"); }

L'exemple de code suivant montre comment remplacer complètement un document existant par un nouveau document à l'aide de replaceOne() cette méthode, plutôt que de mettre à jour des champs individuels. La replaceOne() méthode remplace l'intégralité du document, en préservant uniquement le _id champ de l'original. Si plusieurs documents répondent aux critères du filtre, seul le premier document rencontré est remplacé.

Document newDocument = new Document() .append("restaurantId", "REST-0Y9GL0") .append("name", "Bhiryani Adda") .append("cuisine", "Indian") .append("rating", new Document() .append("average", 4.8) .append("totalReviews", 267)) .append("features", Arrays.asList("Outdoor Seating", "Live Music")); UpdateResult result = collection.replaceOne( Filters.eq("restaurantId", "REST-0Y9GL0"), newDocument); System.out.printf("Modified %d document%n", result.getModifiedCount());

Mettre à jour plusieurs documents

Il existe deux manières de mettre à jour simultanément plusieurs documents d'une collection. Vous pouvez utiliser la updateMany() méthode ou utiliser la méthode UpdateManyModelavec la bulkWrite() méthode. La updateMany() méthode utilise un paramètre de filtre pour sélectionner les documents à mettre à jour, le Update paramètre pour identifier les champs à mettre à jour et un UpdateOptions paramètre facultatif pour spécifier les options de mise à jour.

L'exemple de code suivant illustre l'utilisation de la updateMany() méthode :

Bson filter = Filters.and( Filters.in("features", Arrays.asList("Private Dining")), Filters.eq("cuisine", "Thai")); UpdateResult result1 = collection.updateMany(filter, Updates.set("priceRange", "$$$"));

L'exemple de code suivant illustre la bulkWrite() méthode utilisant la même mise à jour :

BulkWriteOptions options = new BulkWriteOptions().ordered(false); List < WriteModel < Document >> updates = new ArrayList < > (); Bson filter = Filters.and( Filters.in("features", Arrays.asList("Private Dining")), Filters.eq("cuisine", "Indian")); Bson updateField = Updates.set("priceRange", "$$$"); updates.add(new UpdateManyModel < > (filter, updateField)); BulkWriteResult result = collection.bulkWrite(updates, options); System.out.printf("Modified %d document%n", result.getModifiedCount());

Supprimer des documents d'une collection DocumentDB

Le pilote Java MongoDB permet deleteOne() de supprimer un seul document et deleteMany() de supprimer plusieurs documents répondant à des critères spécifiques. Tout comme la mise à jour, l'opération de suppression peut également être utilisée avec la bulkWrite() méthode. Les deux deleteOne() et deleteMany() renvoient un DeleteResultobjet fournissant des informations sur le résultat de l'opération, y compris le nombre de documents supprimés. Voici un exemple d'utilisation deleteMany() pour supprimer plusieurs documents :

Bson filter = Filters.and( Filters.eq("cuisine", "Thai"), Filters.lt("rating.totalReviews", 50)); DeleteResult result = collection.deleteMany(filter); System.out.printf("Deleted %d document%n", result.getDeletedCount());

Gestion des erreurs avec la logique de nouvelle tentative

Une stratégie robuste de gestion des erreurs pour Amazon DocumentDB doit implémenter la catégorisation des erreurs en erreurs réessayables (comme les délais d'attente réseau, problèmes de connexion) et les erreurs non réessayables (comme les échecs d'authentification, les requêtes non valides). En cas d'échec d'opération dû à des erreurs qui doivent être réessayées, il doit implémenter un délai entre chaque nouvelle tentative ainsi que le nombre maximum de tentatives de tentative. Les opérations CRUD doivent se situer dans un bloc trycatch contenant les captures MongoExceptionet ses sous-classes. En outre, il devrait inclure la surveillance et l'enregistrement des erreurs pour une visibilité opérationnelle. Voici un exemple de code qui montre comment implémenter la gestion des erreurs de nouvelle tentative :

int MAX_RETRIES = 3; int INITIAL_DELAY_MS = 1000; int retryCount = 0; while (true) { try { crud_operation(); //perform crud that will throw MongoException or one of its subclass break; } catch (MongoException e) { if (retryCount < MAX_RETRIES) { retryCount++; long delayMs = INITIAL_DELAY_MS * (long) Math.pow(2, retryCount - 1); try { TimeUnit.MILLISECONDS.sleep(delayMs); } catch (InterruptedException t) { Thread.currentThread().interrupt(); throw new RuntimeException("Retry interrupted", t); } continue; } else throw new RuntimeException("Crud operation failed", e); } }