Command and Query Responsibility Segregation (CQRS) mintaCommand and Query Responsibility Segregation (CQRS) pattern

A lekérdezési és manipulációs szerepek szétválasztása (CQRS) minta elválasztja az adattár olvasási és frissítési műveleteit.The Command and Query Responsibility Segregation (CQRS) pattern separates read and update operations for a data store. A CQRS megvalósítása az alkalmazásban maximalizálhatja a teljesítményt, a méretezhetőséget és a biztonságot.Implementing CQRS in your application can maximize its performance, scalability, and security. A CQRS-re való Migrálás által létrehozott rugalmasság lehetővé teszi, hogy a rendszer az idő múlásával jobban fejlődjön, és megakadályozza, hogy a frissítési parancsok az egyesítési ütközéseket okozzák a tartományi szinten.The flexibility created by migrating to CQRS allows a system to better evolve over time and prevents update commands from causing merge conflicts at the domain level.

A problémaThe problem

A hagyományos architektúrák esetében ugyanaz az adatmodell használatos az adatbázisok lekérdezésére és frissítésére.In traditional architectures, the same data model is used to query and update a database. Ez egyszerű és jól működik, ha alapszintű CRUD-műveletekről van szó.That's simple and works well for basic CRUD operations. Összetettebb alkalmazások esetében azonban ez a megközelítés nehézkessé válhat.In more complex applications, however, this approach can become unwieldy. Például az olvasási oldalon az alkalmazás számos különböző lekérdezést végezhet, amelyek különböző típusú adatátviteli objektumokat (DTO-kat) adnak vissza.For example, on the read side, the application may perform many different queries, returning data transfer objects (DTOs) with different shapes. Az objektumok leképezése igen bonyolulttá válthat.Object mapping can become complicated. A írási oldalon a modell összetett érvényesítési és üzleti logikát valósíthat meg.On the write side, the model may implement complex validation and business logic. Ennek eredményeképpen egy túlzottan összetett, túl sok feladatot végző modell jöhet létre.As a result, you can end up with an overly complex model that does too much.

Az olvasási és írási feladatok gyakran aszimmetrikusak, és nagyon eltérő teljesítmény-és méretezési követelményekkel rendelkeznek.Read and write workloads are often asymmetrical, with very different performance and scale requirements.

Hagyományos CRUD-architektúra

  • Az adatolvasási és írási műveletek (például a további oszlopok vagy tulajdonságok) közötti eltérések gyakran még akkor is megfelelőek, ha a művelet részeként nem szükségesek.There is often a mismatch between the read and write representations of the data, such as additional columns or properties that must be updated correctly even though they aren't required as part of an operation.

  • Az adattartalom akkor fordulhat elő, ha a műveleteket párhuzamosan hajtják végre ugyanazon az adathalmazon.Data contention can occur when operations are performed in parallel on the same set of data.

  • A hagyományos megközelítés negatív hatással lehet a teljesítményre az adattár és az adatelérési réteg terhelése miatt, valamint az információk lekéréséhez szükséges lekérdezések összetettségét.The traditional approach can have a negative effect on performance due to load on the data store and data access layer, and the complexity of queries required to retrieve information.

  • A biztonság és az engedélyek kezelése összetett lehet, mivel az egyes entitások olvasási és írási műveleteket is tartalmazhatnak, amelyek helytelen kontextusban tehetik ki az adatokhoz.Managing security and permissions can become complex, because each entity is subject to both read and write operations, which might expose data in the wrong context.

MegoldásSolution

A CQRS elkülöníti az olvasási és írási műveleteket különböző modellekre, az adatokat frissítő parancsokkal és az adatolvasási lekérdezésekkel .CQRS separates reads and writes into different models, using commands to update data, and queries to read data.

  • A parancsoknak feladatalapúnak kell lenniük ahelyett, hogy adatközpontúak lennének.Commands should be task based, rather than data centric. ("Foglaljon szállodai szobát", nem "a ReservationStatus beállítása fenntartva").("Book hotel room", not "set ReservationStatus to Reserved").
  • A parancsok aszinkron feldolgozásra helyezhetők várólistára, nem pedig szinkron módon.Commands may be placed on a queue for asynchronous processing, rather than being processed synchronously.
  • A lekérdezések soha nem módosítják az adatbázist.Queries never modify the database. A lekérdezés egy olyan DTO-t ad vissza, amely nem tartalmaz a környezettel kapcsolatos ismerteket.A query returns a DTO that does not encapsulate any domain knowledge.

A modellek ezután elkülöníthetők, ahogy az alábbi ábrán is látható, bár ez nem feltétlenül követelmény.The models can then be isolated, as shown in the following diagram, although that's not an absolute requirement.

Alapszintű CQRS-architektúra

A különálló lekérdezési és frissítési modellek leegyszerűsítik a tervezést és a megvalósítást.Having separate query and update models simplifies the design and implementation. Azonban az egyik hátránya, hogy az CQRS-kód nem hozható létre automatikusan egy adatbázis-sémából az olyan állványzat-mechanizmusok használatával, mint az O/RM-eszközök.However, one disadvantage is that CQRS code can't automatically be generated from a database schema using scaffolding mechanisms such as O/RM tools.

A nagyobb mértékű elkülönítés érdekében fizikailag is elkülönítheti az olvasási és az írási adatokat.For greater isolation, you can physically separate the read data from the write data. Ebben az esetben az olvasási adatbázis használhatja a saját, lekérdezésekhez optimalizált adatsémáját.In that case, the read database can use its own data schema that is optimized for queries. Például tárolhatja az adatok materializált nézetét, a bonyolult illesztések vagy O/RM-leképezések elkerülése érdekében.For example, it can store a materialized view of the data, in order to avoid complex joins or complex O/RM mappings. Sőt, akár eltérő típusú adattárat is használhat.It might even use a different type of data store. Például az írási adatbázis lehet relációs, míg az olvasási adatbázis lehet egy dokumentum-adatbázis.For example, the write database might be relational, while the read database is a document database.

Ha külön olvasási és írási adatbázist használ, azokat szinkronban kell tartani. Ez általában úgy valósítható meg, hogy az írási modell közzétesz egy eseményt, amikor frissíti az adatbázist.If separate read and write databases are used, they must be kept in sync. Typically this is accomplished by having the write model publish an event whenever it updates the database. Az események használatáról az eseményvezérelt architektúra stílusacímű témakörben olvashat bővebben.For more information about using events, see Event-driven architecture style. Az adatbázis frissítésének és az esemény közzétételének egy tranzakción belül kell megtörténnie.Updating the database and publishing the event must occur in a single transaction.

CQRS-architektúra külön olvasási és írási tárolókkal

Az olvasási tároló lehet az írási tároló csak olvasható replikája, de az olvasási és írási tárolók lehetnek teljesen eltérő szerkezetűek is.The read store can be a read-only replica of the write store, or the read and write stores can have a different structure altogether. Több írásvédett replika használata növelheti a lekérdezési teljesítményt, különösen az olyan elosztott forgatókönyvekben, ahol az írásvédett replikák az alkalmazás példányaihoz közel találhatók.Using multiple read-only replicas can increase query performance, especially in distributed scenarios where read-only replicas are located close to the application instances.

Az olvasási és írási tárolók különválasztása lehetővé teszi a terhelésnek megfelelő méretezésüket is.Separation of the read and write stores also allows each to be scaled appropriately to match the load. Az olvasási tárolók például jellemzően jóval nagyobb terhelésnek vannak kitéve, mint az írási tárolók.For example, read stores typically encounter a much higher load than write stores.

Egyes CQRS-megvalósítások az Event Sourcing mintát használják.Some implementations of CQRS use the Event Sourcing pattern. Ebben a mintában az alkalmazásállapot események sorozataként tárolódik.With this pattern, application state is stored as a sequence of events. Az egyes események az adatok módosításainak egy halmazát jelölik.Each event represents a set of changes to the data. A jelenlegi állapot az események visszajátszása alapján áll össze.The current state is constructed by replaying the events. Egy CQRS-környezetben az Event Sourcing egyik előnye, hogy ugyanazok az események használhatók a többi összetevő, jelen esetben az olvasási modell értesítéséhez.In a CQRS context, one benefit of Event Sourcing is that the same events can be used to notify other components — in particular, to notify the read model. Az olvasási modell az események használatával pillanatképet készít az aktuális állapotról, ami a lekérdezések esetében hatékonyabb megoldásnak bizonyul.The read model uses the events to create a snapshot of the current state, which is more efficient for queries. Az Event Sourcing azonban bonyolultabbá teszi a kialakítást.However, Event Sourcing adds complexity to the design.

A CQRS előnyei a következők:Benefits of CQRS include:

  • Független skálázás.Independent scaling. A CQRS lehetővé teszi az olvasási és írási számítási feladatok egymástól független méretezését, ezáltal kevesebb zárolási versenyt eredményezhet.CQRS allows the read and write workloads to scale independently, and may result in fewer lock contentions.
  • Optimalizált adatsémák.Optimized data schemas. Az olvasási oldal lekérdezésekre optimalizált sémát, az írási oldal pedig frissítésekhez optimalizált sémát használhat.The read side can use a schema that is optimized for queries, while the write side uses a schema that is optimized for updates.
  • Biztonság.Security. Egyszerűbb meggyőződni arról, hogy csak a megfelelő tartományi entitások végeznek írást az adatokon.It's easier to ensure that only the right domain entities are performing writes on the data.
  • Kockázatok elkülönítése.Separation of concerns. Az olvasási és írási oldalak elkülönítésével könnyebben fenntartható és rugalmas modellek hozhatók létre.Segregating the read and write sides can result in models that are more maintainable and flexible. A bonyolult üzleti logika legnagyobb része az írási modellbe kerül.Most of the complex business logic goes into the write model. Az olvasási modell lehet viszonylag egyszerű.The read model can be relatively simple.
  • Egyszerűbb lekérdezések.Simpler queries. A materializált nézet olvasási adatbázisban való tárolásával elkerülhető, hogy az alkalmazásnak bonyolult illesztésekre legyen szüksége a lekérdezések során.By storing a materialized view in the read database, the application can avoid complex joins when querying.

Megvalósítási problémák és megfontolásokImplementation issues and considerations

A minta megvalósításának bizonyos kihívásai a következők:Some challenges of implementing this pattern include:

  • Összetettség.Complexity. A CQRS alapvető működése egyszerű.The basic idea of CQRS is simple. Viszont bonyolultabbá teheti az alkalmazások kialakítását, különösen akkor, ha az Event Sourcing mintát is tartalmazza.But it can lead to a more complex application design, especially if they include the Event Sourcing pattern.

  • Üzenetküldés.Messaging. Bár a CQRS használatához nincs szükség üzenetkezelésre, az üzenetkezelési szolgáltatást gyakorta használják a parancsok feldolgozására és a frissítési események közzétételére.Although CQRS does not require messaging, it's common to use messaging to process commands and publish update events. Ebben az esetben az alkalmazásnak kezelnie kell az üzenethibákat és az ismétlődő üzeneteket.In that case, the application must handle message failures or duplicate messages. A különböző prioritásokkal rendelkező parancsok kezeléséhez tekintse meg a prioritási sorokra vonatkozó útmutatást.See the guidance on Priority Queues for dealing with commands having different priorities.

  • Végleges konzisztencia.Eventual consistency. Ha elkülöníti az olvasási és írási adatbázisokat, az olvasási adatok elavulttá válhatnak.If you separate the read and write databases, the read data may be stale. Az olvasási modell tárolóját frissíteni kell, hogy tükrözze az írási modell tárolójának módosításait, és nehéz lehet észlelni, ha egy felhasználó elavult olvasási információk alapján adta meg a kérelmet.The read model store must be updated to reflect changes to the write model store, and it can be difficult to detect when a user has issued a request based on stale read data.

Mikor érdemes ezt a mintát használni?When to use this pattern

A következő helyzetekben érdemes megfontolni a CQRS:Consider CQRS for the following scenarios:

  • Együttműködési tartományok, ahol számos felhasználó párhuzamosan fér hozzá ugyanazon az adatbázishoz.Collaborative domains where many users access the same data in parallel. A CQRS lehetővé teszi, hogy az egyesítési ütközések csökkentése érdekében a tartomány szintjén csökkentse a megfelelő részletességgel rendelkező parancsokat, és a felmerülő ütközések egyesíthető legyen a parancs segítségével.CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level, and conflicts that do arise can be merged by the command.

  • Feladatalapú felhasználói felületek, ahol a felhasználók lépésenként haladnak végig egy összetett folyamaton, vagy összetett tartományi modellekkel.Task-based user interfaces where users are guided through a complex process as a series of steps or with complex domain models. Az írási modell egy teljes körű, az üzleti logikával, a bemeneti ellenőrzéssel és az üzleti ellenőrzéssel rendelkező parancssori feldolgozó verem.The write model has a full command-processing stack with business logic, input validation, and business validation. Az írási modell a társított objektumok készletét egyetlen egységként kezelheti az adatváltozásokhoz (egy összesítéshez a DDD-terminológiában), és gondoskodhat arról, hogy ezek az objektumok mindig konzisztens állapotban legyenek.The write model may treat a set of associated objects as a single unit for data changes (an aggregate, in DDD terminology) and ensure that these objects are always in a consistent state. Az olvasási modell nem rendelkezik üzleti logikával vagy érvényesítési veremmel, és csak egy DTO ad vissza a View modellben való használatra.The read model has no business logic or validation stack, and just returns a DTO for use in a view model. Az olvasási modell véglegesen konzisztens az írási modellel.The read model is eventually consistent with the write model.

  • Az adatolvasások teljesítményének finomhangolása az adatírások teljesítményének megfelelően történik, különösen akkor, ha az olvasások száma sokkal nagyobb, mint az írások száma.Scenarios where performance of data reads must be fine tuned separately from performance of data writes, especially when the number of reads is much greater than the number of writes. Ebben az esetben lehetősége van az olvasási modell felskálázására, de csak néhány példányban futtathatja az írási modellt.In this scenario, you can scale out the read model, but run the write model on just a few instances. Alacsony számú írási modell-példány használatával csökkenthető az egyesítési ütközések előfordulása is.A small number of write model instances also helps to minimize the occurrence of merge conflicts.

  • Olyan forgatókönyvek, amelyekben egy fejlesztői csapat az írási modell részét képező összetett tartományi modellre összpontosíthat, egy másik csapat pedig az olvasási modellre és a felhasználói felületekre.Scenarios where one team of developers can focus on the complex domain model that is part of the write model, and another team can focus on the read model and the user interfaces.

  • Olyan forgatókönyvek, amelyekben a rendszer az idő előrehaladtával várhatóan fejlődni fog, így a modell több verzióját is tartalmazhatja, illetve ahol az üzleti szabályok rendszeresen változnak.Scenarios where the system is expected to evolve over time and might contain multiple versions of the model, or where business rules change regularly.

  • Integráció más rendszerekkel, különösen az Event Sourcinggal kombinálva, amely esetben egy alrendszer átmeneti meghibásodása nem lehet hatással a többi alrendszer rendelkezésre állására.Integration with other systems, especially in combination with event sourcing, where the temporal failure of one subsystem shouldn't affect the availability of the others.

Ez a minta nem ajánlott a következő esetekben:This pattern isn't recommended when:

  • A tartomány vagy az üzleti szabályok egyszerűek.The domain or the business rules are simple.

  • Az egyszerű szifilisz-stílusú felhasználói felület és az adatelérési műveletek elegendőek.A simple CRUD-style user interface and data access operations are sufficient.

A CQRS-t érdemes lehet a rendszernek csak az olyan korlátozott részein használni, ahol a leginkább hasznos.Consider applying CQRS to limited sections of your system where it will be most valuable.

Az Event Sourcing és a CQRSEvent Sourcing and CQRS

A CQRS mintát gyakran használják az Event Sourcing mintával együtt.The CQRS pattern is often used along with the Event Sourcing pattern. A CQRS-alapú rendszerek külön olvasási és írási adatmodelleket használnak, amelyek mindegyike a kapcsolódó feladatokhoz van igazítva, és gyakran fizikailag elkülönített tárolóban találhatók.CQRS-based systems use separate read and write data models, each tailored to relevant tasks and often located in physically separate stores. Az esemény-beszerzési mintahasználatakor az események tárolója az írási modell, és a hivatalos információforrás.When used with the Event Sourcing pattern, the store of events is the write model, and is the official source of information. A CQRS-alapú rendszerek olvasási modellje az adatok materializált nézetit biztosítja, általában nagy mértékben denormalizált nézetekként.The read model of a CQRS-based system provides materialized views of the data, typically as highly denormalized views. Ezek a nézetek az alkalmazás felhasználói felületeihez és megjelenítési követelményeihez vannak igazítva, ezzel pedig maximalizálható a megjelenítési és lekérdezési teljesítmény.These views are tailored to the interfaces and display requirements of the application, which helps to maximize both display and query performance.

Ha egy adott időpont aktuális adatai helyett az eseménystreamet használja írási tárolóként, azzal elkerülhetők az egyetlen összesítésen felmerülő frissítési ütközések, valamint maximalizálható a teljesítmény és a méretezhetőség.Using the stream of events as the write store, rather than the actual data at a point in time, avoids update conflicts on a single aggregate and maximizes performance and scalability. Az események az olvasási tároló feltöltéséhez használt adatok materializált nézetének aszinkron létrehozásához használhatók.The events can be used to asynchronously generate materialized views of the data that are used to populate the read store.

Mivel az eseménytároló az információk hivatalos forrása, a materializált nézetek törölhetők, és a rendszer fejlődésekor az összes múltbeli esemény visszajátszható a jelenlegi állapot új ábrázolásának létrehozása érdekében, illetve ha az olvasási modell módosítására van szükség.Because the event store is the official source of information, it is possible to delete the materialized views and replay all past events to create a new representation of the current state when the system evolves, or when the read model must change. A materializált nézetek lényegében az adatok tartós, csak olvasható gyorsítótáraként működnek.The materialized views are in effect a durable read-only cache of the data.

A CQRS és az Event Sourcing minta együttes használatakor vegye figyelembe az alábbiakat:When using CQRS combined with the Event Sourcing pattern, consider the following:

  • Mint minden olyan rendszernél, ahol az írási és az olvasási adattárak elkülönülnek, az ezen mintán alapuló rendszerek esetében csak a végleges konzisztencia valósul meg.As with any system where the write and read stores are separate, systems based on this pattern are only eventually consistent. Az esemény létrehozása és az adattár frissítése között bizonyos fokú késésre lehet számítani.There will be some delay between the event being generated and the data store being updated.

  • A minta összetetté teszi a rendszert, mivel kód létrehozására van szükség az események indításához és kezeléséhez, valamint a lekérdezésekhez vagy az olvasási modellhez szükséges megfelelő nézetek vagy objektumok összeállításához vagy frissítéséhez.The pattern adds complexity because code must be created to initiate and handle events, and assemble or update the appropriate views or objects required by queries or a read model. A CQRS minta az Event Sourcing mintával való együttes használatából eredő összetettség megnehezítheti a sikeres megvalósítást, és a rendszerek tervezése szempontjából is eltérő megközelítést igényel.The complexity of the CQRS pattern when used with the Event Sourcing pattern can make a successful implementation more difficult, and requires a different approach to designing systems. Az Event Sourcing azonban megkönnyítheti a tartomány modellezését, illetve a nézetek újraépítését vagy új nézetek létrehozását, mivel az adatok módosításainak célját megőrzi.However, event sourcing can make it easier to model the domain, and makes it easier to rebuild views or create new ones because the intent of the changes in the data is preserved.

  • A materializált nézetek létrehozásához jelentős feldolgozási időre és erőforrás-használatra van szükség, ha azokat az adott entitások vagy entitásgyűjtemények eseményeinek visszajátszásával és kezelésével az olvasási modellben vagy az adatok leképezéseiben használja.Generating materialized views for use in the read model or projections of the data by replaying and handling the events for specific entities or collections of entities can require significant processing time and resource usage. Ez különösen akkor igaz, ha hosszú időszakok értékeinek összesítésére vagy elemzésére van szükség, mivel előfordulhat, hogy minden kapcsolódó eseményt meg kell vizsgálni.This is especially true if it requires summation or analysis of values over long periods, because all the associated events might need to be examined. Ezt megoldhatja az adatok üzemezett időközönként elkészített pillanatképeinek használatával, például egy adott művelet elvégzéseinek összesített számával vagy egy entitás aktuális állapotával.Resolve this by implementing snapshots of the data at scheduled intervals, such as a total count of the number of a specific action that have occurred, or the current state of an entity.

PéldaExample

Az alábbi kód részleteket mutat be egy CQRS-megvalósítási példából, amely külön definíciót használ az olvasási és írási modellekhez.The following code shows some extracts from an example of a CQRS implementation that uses different definitions for the read and the write models. A modellfelületek nem határozzák meg az alapul szolgáló adattárak jellemzőit, továbbá a felületek elkülönülése miatt a fejlődésük és finomhangolásuk is függetlenül valósulhat meg.The model interfaces don't dictate any features of the underlying data stores, and they can evolve and be fine-tuned independently because these interfaces are separated.

A következő kód bemutatja az olvasási modell definícióját.The following code shows the read model definition.

// Query interface
namespace ReadModel
{
  public interface ProductsDao
  {
    ProductDisplay FindById(int productId);
    ICollection<ProductDisplay> FindByName(string name);
    ICollection<ProductInventory> FindOutOfStockProducts();
    ICollection<ProductDisplay> FindRelatedProducts(int productId);
  }

  public class ProductDisplay
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal UnitPrice { get; set; }
    public bool IsOutOfStock { get; set; }
    public double UserRating { get; set; }
  }

  public class ProductInventory
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public int CurrentStock { get; set; }
  }
}

A rendszer lehetővé teszi a felhasználóknak számára a termékek értékelését.The system allows users to rate products. Az alkalmazás kódja ezt az alábbi kódban szereplő RateProduct parancs használatával éri el.The application code does this using the RateProduct command shown in the following code.

public interface ICommand
{
  Guid Id { get; }
}

public class RateProduct : ICommand
{
  public RateProduct()
  {
    this.Id = Guid.NewGuid();
  }
  public Guid Id { get; set; }
  public int ProductId { get; set; }
  public int Rating { get; set; }
  public int UserId {get; set; }
}

A rendszer a ProductsCommandHandler osztályt használja az alkalmazás által küldött parancsok kezelésére.The system uses the ProductsCommandHandler class to handle commands sent by the application. Az ügyfelek általában egy üzenetkezelő rendszeren, például egy üzenetsoron keresztül küldenek a parancsokat a tartománynak.Clients typically send commands to the domain through a messaging system such as a queue. A parancskezelő fogadja ezeket a parancsokat, és meghívja a tartományi felület metódusait.The command handler accepts these commands and invokes methods of the domain interface. Az egyes parancsok részletességének célja a kérések ütközési esélyeinek csökkentése.The granularity of each command is designed to reduce the chance of conflicting requests. A következő kód a ProductsCommandHandler osztály vázlatát mutatja be.The following code shows an outline of the ProductsCommandHandler class.

public class ProductsCommandHandler :
    ICommandHandler<AddNewProduct>,
    ICommandHandler<RateProduct>,
    ICommandHandler<AddToInventory>,
    ICommandHandler<ConfirmItemShipped>,
    ICommandHandler<UpdateStockFromInventoryRecount>
{
  private readonly IRepository<Product> repository;

  public ProductsCommandHandler (IRepository<Product> repository)
  {
    this.repository = repository;
  }

  void Handle (AddNewProduct command)
  {
    ...
  }

  void Handle (RateProduct command)
  {
    var product = repository.Find(command.ProductId);
    if (product != null)
    {
      product.RateProduct(command.UserId, command.Rating);
      repository.Save(product);
    }
  }

  void Handle (AddToInventory command)
  {
    ...
  }

  void Handle (ConfirmItemsShipped command)
  {
    ...
  }

  void Handle (UpdateStockFromInventoryRecount command)
  {
    ...
  }
}

Az alábbi minták és útmutatások hasznosak lehetnek a minta használatakor:The following patterns and guidance are useful when implementing this pattern:

  • Adatkonzisztencia– ismertető.Data Consistency Primer. Részletezi az olvasási és írási adattárak végleges konzisztenciája által okozott általánosan felmerülő problémákat a CQRS minta használatakor, illetve azt is, hogy ezek a problémák hogyan oldhatók meg.Explains the issues that are typically encountered due to eventual consistency between the read and write data stores when using the CQRS pattern, and how these issues can be resolved.

  • Adatparticionálási útmutató.Data Partitioning Guidance. Az az ajánlott eljárásokat ismerteti az adatpartíciók közötti elosztásra, amelyek a méretezhetőség, a verseny csökkentése és a teljesítmény optimalizálása érdekében külön kezelhetők és elérhetők.Describes best practices for dividing data into partitions that can be managed and accessed separately to improve scalability, reduce contention, and optimize performance.

  • Esemény-beszerzési minta.Event Sourcing pattern. Részletesebben ismerteti, hogyan használható az Event Sourcing a CQRS mintával a feladatok egyszerűsítéséhez az összetett tartományokban a teljesítmény, a méretezhetőség és a válaszkészség növelése mellett.Describes in more detail how Event Sourcing can be used with the CQRS pattern to simplify tasks in complex domains while improving performance, scalability, and responsiveness. Emellett azt is bemutatja, hogyan biztosítható a tranzakciós adatok konzisztenciája a teljes körű naplók és előzmények fenntartása mellett, ami lehetővé teszi a kompenzáló műveletek végrehajtását.As well as how to provide consistency for transactional data while maintaining full audit trails and history that can enable compensating actions.

  • Anyagbeli nézet mintája.Materialized View pattern. A CQRS megvalósítás olvasási modellje tartalmazhatja az írási modell adatainak materializált nézeteit, illetve a materializált nézetek létrehozására is használható.The read model of a CQRS implementation can contain materialized views of the write model data, or the read model can be used to generate materialized views.

  • Minták és gyakorlatok útmutatója – A CQRS felfedezése.The patterns & practices guide CQRS Journey. Különösen, ha bemutatjuk a parancs lekérdezési felelősségének elkülönítésére szolgáló mintát , a minta és a hasznos, valamint az Epilógus: az elsajátított tapasztalatok segítenek megérteni a minta használatakor felmerülő problémákat.In particular, Introducing the Command Query Responsibility Segregation pattern explores the pattern and when it's useful, and Epilogue: Lessons Learned helps you understand some of the issues that come up when using this pattern.

Közösségi erőforrásokCommunity resources

Martin Fowler blogbejegyzései:Martin Fowler's blog posts: