2013-08-02 5 views
0

J'ai une application mongo simple qui se trouve être asynchrone (en utilisant Akka). J'envoie un message à un acteur, qui à son tour écrit 3 enregistrements dans une base de données. J'utilise WriteConcern.SAFE parce que je veux être sûr que l'écriture est arrivée (aussi essayé WriteConcern.FSYNC_SAFE).MongoDB WriteConcern Java Driver

Je fais une pause pendant une seconde pour laisser les écritures se produire, puis faire une lecture - et ne rien obtenir.

donc mon code d'écriture peut-être:

collection.save(myObj, WriteConcern.SAFE) 
println("--1--") 
collection.save(myObj, WriteConcern.SAFE) 
println("--2--") 
collection.save(myObj, WriteConcern.SAFE) 
println("--3--") 

puis dans mon code de test (en cours d'exécution en dehors de l'acteur - dans un autre thread) imprimer le nombre de disques que je trouve:

println(collection.findAll(...)) 

Ma sortie ressemble à ceci:

--1-- 
--2-- 
--3-- 
(pauses) 
0 

en effet, si je regarde dans la base de données que je ne vois pas les enregistrements. Parfois, je vois effectivement des données là et le test fonctionne. Le code asynchrone peut être difficile et il est possible que le code de test soit atteint avant que les écritures ne se produisent. J'ai donc également essayé d'imprimer des horodatages pour m'assurer qu'ils sont exécutés dans l'ordre présenté - ils le sont. Les données devraient être là. Exemple de sortie ci-dessous w/horodatages:

Saved: brand_1/dev 1375486024040 
Saved: brand_1/dev2 1375486024156 
Saved: brand_1/dev3 1375486024261 
         1375486026593 0 found 

Ainsi, le 3 Savès clairement arrivé (et aurait dû écrire) un plein 2 secondes avant que la lecture a été tentée. Je comprends pour plus libéral WriteConcerns que vous pourriez obtenir ce comportement, mais je pensais que les deux plus sûrs m'assureraient l'écriture réellement arrivé avant de continuer.

+0

Les sorties d'horodatage de votre application prouvent seulement que les opérations ont été exécutées dans l'ordre, mais cela ne prouve pas que lors de l'exécution de la requête de comptage, MongoDB aurait dû terminer les insertions. Notez également qu'une pause n'est pas un moyen fiable de gérer les appels asynchrones. Vous avez vraiment besoin de rappels et d'un flux de contrôle. Cependant, une attente de 2 secondes est amplement suffisante pour effectuer 3 insertions, car les insertions sur des documents de taille standard devraient se faire en quelques ms ou moins. Quel pilote Java utilisez-vous? Utilisez-vous le pilote async de la communauté ou le pilote natif MongoDB? –

+0

J'utilise le pilote java 2.11.2 via casbah. La pause est nécessaire car les écritures se produisent profondément dans le chemin logique asynchrone alors que la lecture fait partie d'une suite de tests (scalatest). Le code de production ne repose pas sur des pauses ... le test doit juste attendre assez de temps pour s'assurer que tout s'est bien passé. Mon gratte-tête est que je pensais que le SAFE ou FSYNC_SAFE WriteConcern était censé s'assurer que l'écriture se produisait avant de retourner le contrôle, ce qui signifiait qu'en théorie l'écriture devrait être faite quand l'horodatage est imprimé. Ces résultats me font douter de ma compréhension de ces "WriteConcerns". – Greg

+0

Problème d'écriture Safe s'assure d'écrire les informations d'erreur renvoyées au client, ce qui peut être lié à la mise en réseau, à la violation des contraintes telles que les clés dupe et à d'autres erreurs (http://docs.mongodb.org/manual/core/write-concern/). Ceci est opposé à "ignorer et ignorer" les écritures non reconnues. Fsync signifie que MongoDB répondra avec des informations d'erreur seulement après que votre écriture a été vidée dans les fichiers de données. Normalement, MongoDB écrit juste dans la mémoire virtuelle (fichiers de carte mem), et sous le chemin de code typique, vider les changements dans les fichiers de données et/ou le journal de façon asynchrone. –

Répondre

0

Problème subtil mais simple. J'utilisais un def pour créer ma connexion ... que j'ai ensuite appelé deux fois comme si c'était un val. J'ai donc eu 2 écrivains différents, ce qui explique la différence parfois dans mes résultats. Refactorisé à un val et tout était prévisible. Agonisant pour identifier, facile à comprendre/réparer.

Questions connexes