0

MongoDB と対話するときに DB 制約エラーを正しく受信して処理する方法を理解するのに苦労しています。

私は使用しています:

  • MongoDB Java ドライバー - 2.11
  • spring-data-mongodb - 1.2.1.RELEASE
  • spring-framework-core - 3.1.0.RELEASE

私は mongoTemplate.insert を使用して、サッカー チームを表す「persistentTeam」オブジェクトを与えています。いくつかのビジネス ルールに従って、Document の _id フィールドをカスタム生成しています。この _id を生成するアルゴリズムが既存のオブジェクトと一致する可能性があります。その場合、何らかのエラー処理を行いたいと考えています。

デフォルト設定では、ID が重複するオブジェクトを挿入しても、DB からエラーは返されません。これは、デフォルトのmongoドライバー構成が「ACKNOWLEDGED」であり、この場合は例外が発生するはずであると述べているmongoドキュメントと矛盾しています:http://docs.mongodb.org/manual/release-notes/drivers-write-concern/ 私が見た2.11 mongo ドライバー コードと確かに、Mongo.java のデフォルトの書き込み懸念は WriteConcern.NORMAL (UNACKNOWLEDGED と同等) です。わかりました、私は回避します。

編集: コード/ドキュメントの不一致に関する追加の注意事項: Mongo Java Driver 2.10.0 では、Mongo.java を置き換える MongoClient.java が導入されました。ただし、spring-framework-core 3.1.0.RELEASE はこの新しいクラスと統合されません。これが、期待されるデフォルトが得られない理由です。

モンゴファクトリーを更新しました:

<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
    <property name="host" value="${db.url}" />
    <property name="writeConcern" value="ACKNOWLEDGED" />
</bean>

重複した主キーを持つオブジェクトを挿入しようとすると、次のエラーが表示されます。

{"com.mongodb.MongoException$DuplicateKey: {
\"serverUsed\" : \"localhost/127.0.0.1:27017\" ,
\"err\" : \"E11000 duplicate key error index: Sports.persistentTeam.$_id_  dup key: { : 5019964551640473690 }\" ,
\"code\" : 11000 ,
\"n\" : 0 ,
\"connectionId\" : 21 , \"ok\" : 1.0}\n
\tat com.mongodb.CommandResult.getException(CommandResult.java:74)\n
\tat com.mongodb.CommandResult.throwOnError(CommandResult.java:110)\n
\tat com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:76)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:60)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:105)\n
\tat org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:835)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:388)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:830)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:659)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:613)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:604)\n
\tat com.example.persistence.dao.MongoDataServiceDao.create(MongoDataServiceDao.java:96)\n
\tat com.example.persistence.PersistenceImpl.createObject(PersistenceImpl.java:944)\n
}

よし、よし!それはすべて機能しています。そうではありません。成功するはずのものを挿入しようとすると、次のエラーが発生します。

{
com.mongodb.WriteConcernException: 
{ \"serverUsed\" : \"localhost/127.0.0.1:27017\" ,
\"n\" : 0 ,
\"connectionId\" : 20 ,
\"wnote\" : \"no replication has been enabled, so w=\\\"ACKNOWLEDGED\\\" won't work\" ,
\"err\" : \"norepl\" ,
\"ok\" : 1.0}
\n\tat com.mongodb.CommandResult.getException(CommandResult.java:77)\n
\tat com.mongodb.CommandResult.throwOnError(CommandResult.java:110)\n
\tat com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)\n
\tat com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)\n
\tat com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:76)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:60)\n
\tat com.mongodb.DBCollection.insert(DBCollection.java:105)\n
\tat org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:835)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:388)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:830)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:659)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:613)\n
\tat org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:604)\n
\tat com.example.mongo.persistence.dao.MongoDataServiceDao.create(MongoDataServiceDao.java:96)\n
\tat com.example.persistence.PersistenceImpl.createObject(PersistenceImpl.java:944)\n
}

したがって、これは少し混乱します。このエラーは、レプリケーションなしで ACKNOWLEDGED を使用できないことを示しています。しかし、ドキュメンテーションはこれを言っていません。レプリカへの書き込みをチェックすることを明示的に示す他の WriteConcern モードがあります...ACKNOWLEDGED は、プライマリへの書き込みのみを検証する必要があります。そして、結局、書き込みは実際に成功しました。ここで何をすればいいですか?この 2 番目の例外を埋めて忘れてしまいますか?

4

1 に答える 1

2

これは、 の String バリアントを使用しているためですWriteConcern

そうすれば、ドライバーはそれをレプリカ タグ セットの書き込み懸念と見なします。したがって、例外です。

WriteConcernコンストラクターに int バリアントを使用し、肯定応答の値である1の値 ( のように{w=1}) を指定します。

于 2013-07-29T17:15:19.993 に答える