uygulama motorunda JDO 2.3 kullanıyorum yazmaz. Yerel test için Master/Slave veri deposunu kullanıyordum ve yakın zamanda yerel testler için HRD veri deposunu kullanmaya geçtim ve uygulamamın bazı bölümleri kırılıyor (bu da beklenen). Çarpışan uygulamanın bir kısmı, hızlıca çok sayıda yazının gönderildiği yerdir - bunun nedeni 1 saniyelik sınırlama nedeniyle, eşzamanlı bir değişiklik istisnasıyla başarısız oluyor.Gönderilen JDO, yerel GAE HRD veya muhtemelen yeniden kullanılan işlem
Tamam, bu da beklenen bir durumdur, dolayısıyla tarayıcı başarısız olduklarında daha sonra tekrar yazmayı tekrar deneyebilirim (belki de en iyi kesmek değil, sadece çabucak çalışıyorum).
Ama garip bir şey oluyor. Başarılı olması gereken bazı yazımlar (eşzamanlı modifikasyon istisnasını DON'NUYOR), taahhüt aşaması tamamlansa ve istek benim başarı kodumu döndürse de başarısız oluyor. Günlüğünden, yeniden denenen isteklerin düzgün çalıştığını görebiliyorum, ancak ilk denemede işlenmiş görünen diğer talepler, asla "uygulanmadı". Ama başvuru aşaması ile ilgili okuduklarımdan, aynı varlığa tekrar yazmak, başvuruyu zorlamalıdır ... ama değil.
Kod izler. Dikkat Edilmesi Gereken Noktalar:
- automatic JDO caching'u kullanmaya çalışıyorum. Bu yüzden JDO, kapakların altında memcache kullanıyor. Bu, aslında her şeyi bir işlemde sarmadan çalışmaz.
- Tüm istekleri yapmak, bir varlığın bir dizesini okumak, dizenin bir kısmını değiştirmek ve bu dizeyi varlığa geri kaydetmek. Bu istekler işlemlerde değilse, elbette "kirli okuma" problemine sahip olacaksınız. Ancak işlemlerde, izolasyonun "serileştirilebilir" seviyesinde olması gerekiyordu, bu yüzden burada neler olduğunu göremiyorum.
:PersistenceManager pm = PMF.getManager(); Transaction tx = pm.currentTransaction(); String responsetext = ""; try { tx.begin(); // I have extra calls to "makePersistent" because I found that relying // on pm.close didn't always write the objects to cache, maybe that // was only a DataNucleus 1.x issue though Key userkey = obtainUserKeyFromCookie(); User u = pm.getObjectById(User.class, userkey); pm.makePersistent(u); // to make sure it gets cached for next time Key mapkey = obtainMapKeyFromQueryString(); // this is NOT a java.util.Map, just FYI Map currentmap = pm.getObjectById(Map.class, mapkey); Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity Text newMapData = parseModifyAndReturn(mapData); // transform the map currentmap.setMapData(newMapData); // mutate the Map object pm.makePersistent(currentmap); // make sure to persist so there is a cache hit tx.commit(); responsetext = "OK"; } catch (JDOCanRetryException jdoe) { // log jdoe responsetext = "RETRY"; } catch (Exception e) { // log e responsetext = "ERROR"; } finally { if (tx.isActive()) { tx.rollback(); } pm.close(); } resp.getWriter().println(responsetext);
- varlık değiştirilen ben çapraz grup işlemleri
ilgili kod (bu basitleştirilmiş versiyonu olan) sağladı (bir grupta) bir kök varlık
UPDATE: Bunun neden olduğunu bildiğime gayet eminim, ancak yine de bunu onaylayabilecek herkese ödül vereceğim.
Temel olarak, sorunun, işlemlerin yerel veri tabanında gerçekte uygulanmadığı yönündedir. Kaynaklar:
işlemler uygulanmadı Çünkühttps://groups.google.com/forum/?fromgroups=#!topic/google-appengine-java/gVMS1dFSpcU https://groups.google.com/forum/?fromgroups=#!topic/google-appengine-java/deGasFdIO-M https://groups.google.com/forum/?hl=en&fromgroups=#!msg/google-appengine-java/4YuNb6TVD6I/gSttMmHYwo0J
, geri alma esasen no-operasyon. Bu nedenle, iki işlem aynı anda kaydı değiştirmeye çalışırken kirli bir okuma alıyorum. Başka bir deyişle, A verileri okur ve B aynı zamanda verileri okur. Verileri değiştirmeye yönelik girişimler ve B, verilerin farklı bir bölümünü değiştirmeye çalışır. Bir detastore yazıyor, sonra B yazıyor, A'nın değişikliklerini yok ediyor. Ardından B, uygulama motoru tarafından "geri alınır", ancak geri bildirimler yerel veri deposunda çalışırken no-op olduğundan, B değişiklikleri değişmez ve A olmaz. Bu arada, B istisnayı attıran iş parçacığı olduğu için, istemci B'yi yeniden dener, ancak A'yı yeniden denemez (çünkü A, başarılı bir işlemdi).
Eğer datastore yeniden tasarlama düşündünüz mü yerli yolu öğrenmeye değer olduğunu ve çok kez saniyede birden aynı varlık grubuna devam eden önlemek için, nasıl kullanacağımız? Alternatif olarak, datastore için sıralanan görevlere devam etmeyi ve 1/s taraf grubunun yazma frekans sınırına uymaya yönelik düzenlemeleri yapmayı denediniz mi? –
Bunu düşündüm. Ama bunu yapmadan önce, bu özel hatanın neden olduğunu anlamak isterim ... endişem, temel olarak İKG veya uygulama motoru/jdo işlemleri veya bir şey hakkında bir şey anlamadığım veya bir şeyi özlediğim dokümantasyon ve ben şimdiki eklenti kullanarak, – eeeeaaii
FWIW (veri deposu erişimler bir işlemde değilse çalışmaz JDO önbelleğe) için işlemleri eklemem gerekiyor en az 25 diğer hizmetler var çünkü (daha sonra Gae beni ısıracak JDO v2.x), L2 önbelleğinin çalışması için bir işlemde bulunma gerekliliğini görmüyorum; eğer bir nesne okunduğunda L2 önbelleğe alınmışsa ve rapor edilmemişse (eski eklenti desteklenmiyorsa, o zaman sadece güncel bir durum söz konusuysa). – DataNucleus