DDD, Saga ve Olay kaynağı: Bir Telafi Eylemi yalnızca olay deposunda silinebilir mi?


15

Yukarıdaki sorunun muhtemelen birkaç 'ne ??' yükseltir, ancak açıklamaya çalışalım:

Ben ilgili kavramların bir çift kafamı temelde Saga-desen (sarmak için çalışıyorum http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf Olay kaynak ile birlikte) (A DDD-konsept : http://en.wikipedia.org/wiki/Domain-driven_design )

Birlikte saran güzel bir yazı: https://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/

Bir dakika içinde soruya geliyorum, ama önce anladığım şeyi özetlemeye çalışmalıyım (bu yanlış olabilir, bu durumda lütfen düzeltin) çünkü bu neden olduğumu iyi etkileyebilir soruyla başlamak için:

  1. Saga deseni, bir işlem (son kullanıcı, otomatik, vb. Temelde veri değiştirecek her şey) veren bir tür brokerdir ve bu eylemleri iş faaliyetlerinde böler ve bu etkinliklerin her birini bir Mesaj Veri Yolu'na mesaj olarak gönderir. sırayla ilgilenilmesi gereken ilgili köklere gönderir.
  2. Bu agrega kökleri tamamen bağımsız olarak çalışabilir (endişelerin güzel bir şekilde ayrılması, büyük ölçeklenebilirlik, vb.)
  3. Saga örneğinin kendisi, etkinlik gönderdiği toplu köklerde bulunan herhangi bir iş mantığı içermez. Saga'da yer alan tek 'mantık', alınan işlemlere (ve ayrıca takip olaylarına) ne yapılacağını (yani hangi aktivitelerin gönderileceğini) belirleyen 'süreç' mantığıdır (genellikle bir Statemachine olarak uygulanır).
  4. Saga örüntüleri bir tür dağıtılmış işlem örüntüsü uygular. Yani: agrega köklerinden biri (birbirinin varlığını bilmeden tekrar özerk bir şekilde çalışır) başarısız olduğunda, tüm eylemin geri alınması gerekebilir.
  5. Bu, faaliyet raporlarının Saga'ya geri gönderilmesinden sonra tüm agrega köklerine sahip olarak uygulanır. (Başarı ve hata durumunda)
  6. Tüm agrega köklerinin bir başarıya dönmesi durumunda, Saga bundan sonra ne yapacağını belirlerse (veya yapılmasına karar verirse) iç statemachine
  7. Başarısızlık durumunda, Saga, son eylemde yer alan Tazminat Eylemi olarak adlandırılan tüm toplu köklere, yani: toplam köklerin her birinin yaptığı son eylemi geri almak için bir eylem yayınlar.
  8. Eğer eylem "artı 1 oy" ise bu sadece bir "Eksi 1 oy" yapıyor olabilir, ancak bir blog yazısını önceki sürümüne geri yüklemek gibi daha karmaşık olabilir.
  9. Etkinlik kaynağı oluşturma (bkz. İkisini birleştiren blog yazısı), toplu köklerin her birinin merkezi bir Etkinlik Deposunda üstlendiği etkinliklerin her birinin sonuçlarının kaydedilmesini dışsallaştırmayı amaçlamaktadır (değişikliklere bu bağlamda 'etkinlikler' denir)
  10. Bu Etkinlik deposu 'gerçeğin tek versiyonu'dur ve sadece depolanan olayları tekrarlayarak (aslında bir olay günlüğü gibi) tüm varlıkların durumunu tekrar oynatmak için kullanılabilir
  11. İkisini birleştirmek (yani: agrega köklerinin Saga'ya rapor vermeden önce değişikliklerini kaydetmek için dış kaynak sağlamak için Olay kaynağı kullanmasına izin vermek), biri sorumla ilgili olan çok sayıda güzel olasılık sağlar ...

Tek seferde kavramak çok şey olduğu için bunu omzumdan çıkarmam gerektiğini hissettim. Bu bağlam / zihniyet göz önüne alındığında (yine yanlışsa lütfen düzeltin)

soru: Bir toplu kök bir Telafi Eylemi aldığında ve bu toplu kök Olay kaynağı kullanarak durum değişikliklerini dışa aktardıysa, her durumda Telafi Eylemi yalnızca Olay Deposu'ndaki son olayın silinmesi anlamına gelmez. Toplam Kök mü? (Kalıcı uygulamanın silmeye izin verdiği varsayılarak)

Bu benim için çok anlamlı olurdu (ve bu kombinasyonun bir başka büyük yararı da olurdu), ancak dediğim gibi, bu varsayımları bu kavramların yanlış / eksik bir anlayışına dayandırabilirim.

Umarım bu çok uzun sürmez.

Teşekkürler.

Yanıtlar:


9

Olayları olay mağazanızdan silmemelisiniz. Bunlar olanları temsil eder. Şimdi bir şey olursa, bunu da bilmelisiniz, bu nedenle toplamınızı önceki bir duruma geri dönmeye zorlayacak bir olay ekleyin. Veritabanınızdan bilgi silmek üzücü.

greg young ve kaldırılan eşyalardan sepeti örneği düşünün. Yarın telafi edici eylemin herhangi bir değeri olabilir.

Efsaneye gelince, kendimi bildiğim kadarıyla her şey doğrudur. Efsaneyi bir devlet makinesi olarak düşünmelisiniz. Sadece bunu yapar.

Destanın topluluğa bir şey yapmasını söylemesi için verdiği bir Komuttur. Bu eylemden bir olay olacak. Bu etkinlik, ihtiyacınız olan düzeltici eylem olabilir veya bir görünümde normalleştirilmesi gerekebilir, böylece bazı kullanıcılar ne yapacağına karar vermek için bunu görür.

Bu, iş kurallarınıza bağlıdır. Ya kolay bir düzeltme var: agrega kökü böyle bir durumda bunu yaptığınızı bilir veya seçim programlı olarak yapılamayacak kadar karmaşıktır (geliştirme maliyeti çok yüksektir) ve bu nedenle bunu bazı kullanıcılara önerebilirsiniz. farklı eylemler arasında seçim yapabilir. Her şey telafi edici eylemin bağlamına bağlıdır. Bu saf iş kurallarıdır. Bu durumda ya da bu durumda ne yapmalıyız. Bu, alan adı uzmanınıza sormak için bir şeydir ve daha sonra otomatik bir çözüm geliştirmenin daha iyi olup olmadığını veya çözümün kullanıcıya Ronald R.'ya sormak için olup olmadığını seçin, çünkü genellikle bu soruyu cevaplayan kişi odur.


Agrega hangi duruma geri döneceğini nasıl bilebilir? Etkinlik deposuna veya başka bir şeye karşı sorgulama yapılmasına izin verilir mi?
Geert-Ocak

Geri dönmemeli ama başka bir etkinlik eklemeliydi. Destanın topluluğa bir şey yapmasını söylemesi için verdiği bir Komuttur. Bu eylemden bir olay olacak.
Arthis

Evet anladım. "Geri döndür" muhtemelen kötü seçilmişti. Aşağıdakileri düşünün: Diğer şeylerin yanı sıra Belge yayınlama / onay akışlarını modellemek için Sagas ile Etkinlik Kaynak Kullanımı'nı kullanmak isteyebilirim. Bir düzenleyicinin en sonunda Olay Deposuna bir BlogBodyChanged-olayı olarak kalıcı olan bir ChangeBlogBody-eylemi gönderirse ne olur? Daha sonra, bazı nedenlerden dolayı bir Telafi Davası düzenlenir. Toplama, Blog Gövdesi içeriğiyle sonuçlanan ve tetiklenecek olayı telafi etmek için ChangeBlogBody-action'dan hemen önce nasıl bilecekti?
Geert-Ocak

Bu, iş kurallarınıza bağlıdır. Ya kolay bir düzeltme var: agrega kökü böyle bir durumda bunu yaptığınızı bilir ya da seçim programlı olarak yapılamayacak kadar karmaşıktır (geliştirme maliyeti çok yüksektir) ve bu nedenle bunu bazı kullanıcılara önerebilirsiniz. farklı eylemler arasında seçim yapabilir.
Arthis

Her şey telafi edici eylemin bağlamına bağlıdır. Bu saf iş kurallarıdır. Bu durumda ya da bu durumda ne yapmalıyız. Bu, alan adı uzmanınıza sormak için bir şeydir ve daha sonra otomatik bir çözüm geliştirmenin daha iyi olup olmadığını veya çözümün kullanıcıya Ronald R.'ya sormak için olup olmadığını seçin, çünkü genellikle bu soruyu cevaplayan kişi odur.
Arthis

6

Tamlık için, Martin Fowler'tan durumu geri almanın yolları hakkında alakalı bir pasaj eklemeyi düşündüm:

Kendilerini ileriye doğru oynayan olayların yanı sıra, kendilerini tersine çevirebilmeleri de genellikle yararlıdır.

Ters kayıt, olay bir fark şeklinde verildiğinde en basit olanıdır. Bunun bir örneği, "Martin hesabını 110 $ 'a ayarlamak" yerine "Martin hesabına 10 $ ekle" olacaktır. İlk durumda, sadece 10 $ çıkararak geri çevirebilirim, ancak ikinci durumda hesabın geçmiş değerini yeniden oluşturmak için yeterli bilgim yok.

Girdi olayları fark yaklaşımını izlemiyorsa, olay işleme sırasında geri dönüş için gereken her şeyi kaydettiğinden emin olmalıdır. Bunu, önceki değerleri değiştirilen herhangi bir değere depolayarak veya olaydaki farklılıkları hesaplayıp kaydederek yapabilirsiniz.

Gönderen: http://martinfowler.com/eaaDev/EventSourcing.html


1

kavramsal olarak:

  • Olay olan şey. Geçmiş değiştirilemez.
  • Komuta yapılacak bir şeydir. Komut gerçekleşmeyebilir (reddedilebilir).

Gelecekteki durumumuzu yalnızca, Etkinliklerin uygulamanın durumunun değişmesine neden olacak başka bir komut (Telafi Eylemi) uygulayarak değiştirebiliriz.

Soruyu "karıştırmak" için, "son olayın silinmesi" ifadesini düşünün:

  • Son etkinlik silinecek etkinlik değilse ne olur? Silinecek olandan sonra başka olaylar olursa ne olur? Bu olayların da değiştirilmesi gerekir (çünkü temel durumları önlerindeki olay silinerek değişebilir).
  • Olay harici sisteme gönderildiyse ne olur? Başka bir etkinlik göndermek dışında durumunu düzeltmek için erişiminiz olmayabilir.

Kısacası, CQRS modelindeki olayları silme seçeneğiniz yoktur.

(Bu duruma yol açan tüm olaylara dayanan) bir anlık görüntü durumu oluşturarak Etkinlik Deponuzu küçültebilirsiniz, ancak bu fiziksel yönün etkinlik kavramıyla hiçbir ilgisi yoktur.


0

Geert-Jan, tazminat eyleminin ilgili olay (lar) ı silebileceğini düşünüyorum. Mantıklıdır ve Etkinlik Kaynaklandırma tasarım modelinin başka bir faydasını gösterir: Telafi İşlemi tasarım deseninin daha kolay uygulanması.

Bazıları olayı silmenin olay kaynağı veya CQRS'nin "ilkelerini" ihlal ettiğini söylüyor. Bence bu sınırlayıcı bir genelleme. İptal edilen bir genel işlem kapsamında oluşturulmuşsa bir etkinliği silmenin uygun olduğunu düşünüyorum. Sahte kodu düşünün:

try {
    newEvents = processMycommand(myCommand)
    for (Event newEvent : newEvents)
        EventStore.insertEvent(newEvent);
} catch (Exception e) {
    EventStore.rollback();
}

Etkinlik deponuzun işlemsel bir veritabanı olduğunu varsayalım. Sözde kodda, ilk olayı eklediğiniz durumu hayal edebilirsiniz, ancak ikinci olayı eklemeye çalışırken bir İstisna atıldı. Geri alma komutu doğal olarak ilk etkinliğin eklenmesini geri alır. Bu makul mi?

Bir ACID veritabanı işlemi için makul ise (kesin / geri alma işlemi), telafi edici bir işlem için neden makul olmaz?

Global Saga işlemini gerçekleştirirken veri değişiklikleri geri alınabilir (tazminatla). İşlem tamamlanmadığı için işlem sırasında oluşturulan olayı korumaya gerek yoktur.

Şimdi, tazminat bir olayı silmeye çalışırsa ve bu olay bir nesne üzerindeki en yeni olay değilse, silme gerçekleşmemelidir. Ancak genel olarak, özellikle okuma-yoğun çözümlerde bu gerçekleşme olasılığı düşüktür.


0

Etkinlik deposunun sadece kaydetmek istediğiniz veriler olduğu düşüncesiyle oynayalım. Örneğin bir sabit diskimiz olabilir, en baştan başlayabilir ve üzerine veri yazabiliriz. Her etkinliğimizde önceki verilerimizi ekliyoruz, bu yüzden son kez durduğumuz diske yazmaya devam ediyoruz. Bir olayı kaldırmak istediğimizde geri döneriz, o bölümü diskten çıkarır ve bir boşluk bırakır. Kendi başına geri gitmek, etkinlik depolamamızı yavaşlatır, ancak bununla yaşayabiliriz. Bir dosya sistemi kullanırsak, boşluğu ikinci olaylarla doldurmaya çalışırız, böylece yavaş parçalanmış bir depolamaya sahip oluruz veya birleştirme yapabiliriz. İkisi de sevdiğimiz bir şey değil. Veritabanlarından bahsediyorsak, olaylarınızı depolamak için yalnızca bir ekleme veritabanı yerine ilişkisel bir veritabanı kullanırsanız bunu alırsınız:

resim açıklamasını buraya girin ref: https://cambridge-intelligence.com/bringing-time-series-data-to-life-with-keylines/

Ofc. normal bir site tarafından bu önemli değil, ancak bu çözümler facebook, google, vb. gibi büyük web siteleri için tasarlanmıştır ... Yani gerçekten soru mantıklı değil, çünkü yalnızca bir veritabanına bir etkinliği nasıl silebilirsiniz ve nasıl olur? bir zaman makinesi inşa etmek ve bir olayı değiştirmek veya önlemek için zamanda geriye hareket etmek gibi bir tazminat diyorsunuz ???

Bildiğim kadarıyla. Bunu çözmenin tek yolu, sahip olmak istemediğiniz olayları hariç tuttuğunuz ve bundan sonra eski olay deposunu kaldırarak yeni bir olay deposu oluşturmaktır. Ama bu tek bir olayı kaldırmak için aşırı bir çözüm. GDPR hakkında konuşuyorsak, bildiğim tek iyi çözüm olay deposunda şifrelenmiş kişisel verileri depolamak ve şifreleme anahtarını farklı bir veritabanından kaldırmaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.