2016-04-15 8 views
0

私は、各従業員の残高が異なる毎月末に残高が更新される1000人の従業員(以下のサンプル)のリストがあるシナリオを持っています。スプリングデータMongoDBはバルク更新でデータの整合性を維持しています

{ 
    _id:1 
    name:"John" 
    balance:40 
}, 

ここで同じことを実行するのが最善の方法でしょう。 1

for (Employee employee : employeeList) { 
     employee.update(); 
    } 

または

dropAll employees where id in (All employees ids) 
mongoOperations.insert(employeeList, Employee.class); 

または第三のアプローチずつが

Load all employee records. 
Insert employee records to a new collection say employee_temp. 
Drop old collection (employee). 
Rename newly inserted collection as old one (employee). 

かだけでなく、データベースのデータの整合性の最大の成功のチャンスを保証することができます彼らの他の方法である可能性があり、それを実行しますパフォーマンスの観点から良い。

答えて

0

最初にアプローチしてください。それを一つずつ行います。オブジェクト全体を保存する代わりに、より良いパフォーマンスを示すatomic updatesを使用してください。

Query query = Query.query(Criteria.where("id").is(id)); 
Update update = Update.update("balance", balance); 
mongoTemplate.findAndModify(query, update, FindAndModifyOptions.options().returnNew(true), Employee.class); 

2番目と3番目は縮尺されません。実行時にコレクションを削除することはお勧めできません。名前変更のコレクションはlimitationsです。

+0

私はスケーラビリティに関して2番目の点に同意しました。最初のアプローチの問題は、アトミック更新が単一のドキュメントのみの更新を保証するか、複数のオブジェクトに対して同じバランスの値を更新する必要がある場合でも正常に動作することです。ただし、異なる従業員が異なる残高を持つ場合、複数のクエリの実行につながり、アトミック性の保証が取り消されます。 – tarunkumar

0

私たちが最後に解決したもう1つのアプローチは、私たちのカスタムチェックポイントをロールバックのためにmongoに保存するか、必要なものをコミットすることです(私たちのデータサイズは小さいので1000人の従業員しかない)すべての従業員の状態を保存し、一括更新を開始する前にまず保存してください。最初のレコード挿入が成功した場合は、ロールバックできるDBの状態が少なくともあるか、失敗した場合に一括更新を再実行しようとします。

一括更新プロセスが正常に完了した場合は、チェックポイントコレクションを削除します。失敗した場合、新しい値が従業員レコードと一致しないすべてのレコードの更新を再実行します。

しかし、もしあなたの設計が許せば、ハイブリッドDBの方がいいでしょう。リレーショナルDBにトランザクションデータを保存し、残りはmongoに依存します。