読者です 読者をやめる 読者になる 読者になる

SpringDataのMongoWriterの挙動めも

あんまり調べられてないけど。
なんかマルチスレッドでMongoWriter#writeを使ったとき、JVM起動直後にいくつかのドキュメントがフィールドが不足した状態でinsertされることがありました。
MongoWriter#writeを使ってる具体的なコードは以下のようなかんじ。

Dto dto = new Dto();
dto.setA("a");
dto.setB("b");
dto.setC("c");
DBObject dbObject = new BasicDBObject();
mongoTemplate.getConverter().write(dto, dbObject);
dbObject.removeField(DefaultTypeMapper.DEFAULT_TYPE_KEY);
mongoTemplate.getCollection("testcol").insert(dbObject, WriteConcern.SAFE);

MongoTemplate#insert(Object objectToSave)だと「_class」が入っちゃうので上のような実装にしてますが、MongoTemplate#insert(Object objectToSave)も内部的には同じようにMongoWriter#write呼んでるので再現するっぽい。


dtoが「a」、「b」、「c」というフィールドを持っているとき、上のコードでinsertを行うとどこぞでアルファベット順にソートされてるのか、DBにはアルファベット順に保存されるようです。
フィールド「b」が欠けてinsertされた場合、「c」も欠けている状態になっていました。
フィールド「a」が欠けて「b」や「c」が入るといった挙動は確認できませんでした。


マルチスレッドで実行する前に一度MongoWriter#writeを行ってやるとその後マルチスレッドで実行しても再現しなくなりました。
JVM起動直後にだけ出て、そのあとずっとマルチスレッドでまわしてても再現しないあたりなんかなー。なー。
と思ったらそのあとちょっと気になって、上の処理のあと続けて別のDTOを同じようにマルチスレッドでまわしたらそっちはそっちで再現しました。
変換するclassごとに一旦MongoWriter#writeをやってやらないといけないっぽい感じかなー。うーんうーん。


上のようにMongoTemplate#insert(Object objectToSave)を使わずに自分でMongoWriter#writeをやるならフィールドが欠損してないかチェックする余地はあるけど都度チェックっていうのもなんかなー。
でもやらないとShardKeyとかuniqueIndexじゃないときエラー吐かずにしれっとinsertするしなー。
時間があるときもうちょっと深くまで読み込んでみよう…。

スポンサーリンク