2016-05-17 46 views
8

MongoDB'yi Spring Data aracılığıyla kullanıyoruz ve mevcut varlıkları güncellemek veya yenilerini oluşturmak için findAndModify işlemine güveniyoruz.Hem eski hem de yeni varlıkları Spring/MongoDB findAndModify öğesinden döndürme

findAndModify'da, returnNew(...)'u kullanarak varlığın eski durumunu veya yeni olanını döndürmek üzere yapılandırabiliriz.

Eski ve yeni varlıkları findAndModify'dan döndürmenin bir yolu var mı?

Güncelleştirmelerden önce ve sonra varlık durumlarını karşılaştırmalıyız, bu yüzden her iki örneğe de ihtiyacımız var. Biz requireNew(false) başvurmadan ve sonra el Böyle eski örneğinin bir kopyasını şey güncellemek ediyoruz anda

: Biz aynı şeyleri yeniden yapmak zorunda olduğu

public Pair<Data> saveItems(String id, List<Item> items) { 
    final Query findById = ...; 

    final Update update = new Update(); 
    // This is what we actually update 
    update.set(ENTITY_FIELD_ITEMS, newItems); 
    update.inc(ENTITY_FIELD_VERSION, 1); 
    // Try updating and return the old data 
    final Data oldData = operations.findAndModify(findById, update, 
     FindAndModifyOptions.options().upsert(true).returnNew(false), Data.class); 

    // Copy or create new instance 
    final Data newData; 
    if (oldData == null) { 
     newData = new Data(id); 
    } 
    else { 
     newData = new Data(oldData); 
    } 
    // Apply the same update 
    newData.setItems(newItems); 
    newData.incVersion(); 
    return new Pair<Data>(oldData, newData); 
} 

Çalışır, ancak hoş değil biz Zaten eski örneğinin kopyasında Update'da yapın.

Ayrıca düşündüğümüz, önce eski bir örneği yüklemesi ve güncellemeyi çalıştırmasıydı; ancak, varlık yük ve güncelleştirme arasında değiştirilmiş olabileceğinden emin değil. Bu, sürümler ve iyimser kilitleme ile ele alınabilir, ancak bu, işleri daha da karmaşık hale getirir.

cevap

4

Eski ve yeni varlıkları findAndModify'dan döndürmenin bir yolu var mı?

Hayır

, findAndModify ile hem eski hem de yeni değer döndürmek için hiçbir yolu yoktur.

+0

Evet, başka yol yok gibi görünüyor. – lexicore

0

Hayır, eski ve yeni değerleri findAndModify ile döndürmenin bir yolu yoktur.

Ama daha önce ve aşağıda

  1. adımları yapmak güncellemeden sonra kiflili¤i durumunu karşılaştırmak istiyorsanız Sadece findAndModify sorgu değişikliği returnNew için değişken oldData birincil anahtar ve mağaza
  2. kullanarak veri almak güncellemeden önce gerçek örnek sudocode Aşağıda newData

altında kaydetmek size iki değeri dönecektir

public Pair<Data> saveItems(String id, List<Item> items) { 
    final Query findById = ...; 

    final Update update = new Update(); 
    // This is what we actually update 
    update.set(ENTITY_FIELD_ITEMS, newItems); 
    update.inc(ENTITY_FIELD_VERSION, 1); 
    // Try updating and return the old data 
    final Data oldData = findById(); //query to retrieve existing data 
    final Data newData = operations.findAndModify(findById, update, 
     FindAndModifyOptions.options().upsert(true).returnNew(true), Data.class); 

     return new Pair<Data>(oldData, newData); 
    } 
+0

İlk 'find' ile aşağıdaki' findAndModify' arasında başka bir güncelleme olabilir, bu nedenle 'eskiData' eski olabilir. – lexicore

+0

findAndModify iş parçacığı için güvenlidir, bu nedenle olmayacak ve her iki adım da birbiri ardına gerçekleştikçe kullanım durumunuz yeterli olacaktır. – rajadilipkolli

+0

İş parçacığı güvenliği bununla hiçbir ilgisi yoktur. Paralel olarak birkaç iplik işleme verisi olabilir. Yani "BulmakModify" atomik olsa bile, "bul" ve "findAndModify" dizisi bir dizi değildir. Daha sonra, veritabanına farklı işlemlerden ve hatta makinelerden erişilebilir. 'Find' ve' findAndUpdate' arasında güncelleme işleminin gerçekleşmeyeceğini garanti etmenin bir yolu yoktur. – lexicore