Komut ve Sorgu Sorumluluğu Ayrımı (CQRS) modeliCommand and Query Responsibility Segregation (CQRS) pattern

Ayrı arabirimler kullanarak verileri okuyan işlemleri verileri güncelleştiren işlemlerden ayırın.Segregate operations that read data from operations that update data by using separate interfaces. Bu performansı, ölçeklenebilirliği ve güvenliği en üst düzeye çıkarabilir.This can maximize performance, scalability, and security. Daha yüksek esneklik yoluyla zaman içindeki sistem evrimini destekler ve güncelleştirme komutlarının etki alanı düzeyinde birleştirme çakışmalarına neden olmasını engeller.Supports the evolution of the system over time through higher flexibility, and prevents update commands from causing merge conflicts at the domain level.

Bağlam ve sorunContext and problem

Geleneksel veri yönetimi sistemlerinde komutlar (veri güncelleştirmeleri) ve sorgular (veri istekleri), tek bir veri deposundaki aynı varlık kümelerine karşı yürütülür.In traditional data management systems, both commands (updates to the data) and queries (requests for data) are executed against the same set of entities in a single data repository. Bu varlıklar, SQL Server gibi bir ilişkisel veritabanında bulunan bir veya daha fazla tablodaki satırların alt kümesi olabilir.These entities can be a subset of the rows in one or more tables in a relational database such as SQL Server.

Genellikle bu sistemlerde oluşturma, okuma, güncelleştirme ve silme (CRUD) işlemlerinin tümü varlığın aynı temsiline uygulanır.Typically in these systems, all create, read, update, and delete (CRUD) operations are applied to the same representation of the entity. Örneğin, bir müşteriyi temsil eden veri aktarımı nesnesi (DTO), veri erişimi katmanı (DAL) tarafından veri deposundan alınır ve ekranda görüntülenir.For example, a data transfer object (DTO) representing a customer is retrieved from the data store by the data access layer (DAL) and displayed on the screen. Kullanıcı DTO’nun bazı alanlarını güncelleştirir (örneğin, veri bağlama aracılığıyla) ve DTO, DAL tarafından veri deposuna yeniden kaydedilir.A user updates some fields of the DTO (perhaps through data binding) and the DTO is then saved back in the data store by the DAL. Hem okuma hem de yazma işlemi için aynı DTO kullanılır.The same DTO is used for both the read and write operations. Şekilde geleneksel bir CRUD mimarisi gösterilmiştir.The figure illustrates a traditional CRUD architecture.

Geleneksel CRUD mimarisi

Geleneksel CRUD tasarımları, yalnızca veri işlemlerine sınırlı iş mantığı uygulandığında iyi çalışır.Traditional CRUD designs work well when only limited business logic is applied to the data operations. Geliştirme araçları tarafından sağlanan yapı iskelesi mekanizmaları, daha sonra gerekli şekilde özelleştirilebilen veri erişimi kodunu çok hızlı bir şekilde oluşturabilir.Scaffold mechanisms provided by development tools can create data access code very quickly, which can then be customized as required.

Bununla birlikte, geleneksel CRUD yaklaşımının bazı dezavantajları vardır:However, the traditional CRUD approach has some disadvantages:

  • Bu genellikle, verilerin okuma ve yazma temsilleri arasında uyuşmazlık olduğu anlamına gelir. Örneğin, işlemin bir parçası olmaları gerekmedikleri halde doğru şekilde güncelleştirilmesi gereken ek sütun ve özellikler gibi.It often means that there's 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.

  • Birden çok aktörün aynı veri kümesi üzerinde paralel olarak çalıştığı bir işbirliği etki alanındaki veri deposunda kayıtların kilitlenmesi durumunda veri çekişmesi riskine yol açabilir.It risks data contention when records are locked in the data store in a collaborative domain, where multiple actors operate in parallel on the same set of data. Diğer yandan, iyimser kilitleme kullanıldığında eş zamanlı güncelleştirmelerin neden olduğu güncelleştirme çakışması tehlikesi doğurabilir.Or update conflicts caused by concurrent updates when optimistic locking is used. Sistemin karmaşıklığı ve aktarım hızı büyüdükçe, bu riskler artar.These risks increase as the complexity and throughput of the system grows. Bunlara ek olarak, geleneksel yaklaşımda veri deposu ve veri erişim katmanı üzerindeki yükün yanı sıra bilgi almak için gerekli sorguların karmaşıklığı nedeniyle performans olumsuz etkilenebilir.In addition, 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.

  • Her varlık hem okuma hem de yazma işlemlerine tabi olduğu için veriler yanlış bağlamda sunulabileceğinden, bu yaklaşım güvenlik ve izinlerin yönetimini daha karmaşık bir hale getirebilir.It can make managing security and permissions more complex because each entity is subject to both read and write operations, which might expose data in the wrong context.

ÇözümSolution

Komut ve Sorgu Sorumluluğu Ayrımı (CQRS), verileri okuyan işlemler (sorgular) ile verileri güncelleştiren işlemler (komutlar) için ayrı arabirimler kullanarak bunları birbirinden ayıran bir modeldir.Command and Query Responsibility Segregation (CQRS) is a pattern that segregates the operations that read data (queries) from the operations that update data (commands) by using separate interfaces. Bu, sorgulama ve güncelleştirmeler için kullanılan veri modellerinin farklı olduğu anlamına gelir.This means that the data models used for querying and updates are different. Daha sonra bu modeller aşağıdaki şekilde gösterildiği gibi yalıtılabilir, ancak bu mutlak bir gereksinim değildir.The models can then be isolated, as shown in the following figure, although that's not an absolute requirement.

Basit bir CQRS mimarisi

CRUD tabanlı sistemlerde kullanılan tek veri modeli ile karşılaştırıldığında, CQRS tabanlı sistemlerde veriler için ayrı sorgu ve güncelleştirme modelleri kullanılması tasarımı ve uygulamayı basitleştirir.Compared to the single data model used in CRUD-based systems, the use of separate query and update models for the data in CQRS-based systems simplifies design and implementation. Bununla birlikte, CRUD tasarımlarında olmayan bir dezavantaj olarak CQRS kodu iskele mekanizmalarıyla otomatik olarak oluşturulamaz.However, one disadvantage is that unlike CRUD designs, CQRS code can't automatically be generated using scaffold mechanisms.

Verilerin okunmasına yönelik sorgu modeli ile yazılmasına yönelik güncelleştirme modeli aynı fiziksel depoya erişebilir (örneğin SQL görünümlerini kullanarak veya çalışma sırasında izdüşümler oluşturarak).The query model for reading data and the update model for writing data can access the same physical store, perhaps by using SQL views or by generating projections on the fly. Bununla birlikte, performansın, ölçeklenebilirliğin ve güvenliğin en üst düzeye çıkarılması için bir sonraki şekilde gösterildiği gibi verileri farklı fiziksel depolara ayırma yaygın bir uygulamadır.However, it's common to separate the data into different physical stores to maximize performance, scalability, and security, as shown in the next figure.

Ayrı okuma ve yazma depoları içeren bir CQRS mimarisi

Okuma deposu yazma deposunun salt okunur bir çoğaltması olabilir ya da okuma ve yazma depoları tamamen farklı bir yapıda olabilir.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. Okuma deposunun birden çok salt okunur çoğaltmasının kullanılması, özellikle de salt okunur çoğaltmaların uygulama örneklerine yakın olduğu dağıtılmış senaryolarda sorgu performansını ve uygulama arabiriminin yanıt verme hızını önemli ölçüde artırabilir.Using multiple read-only replicas of the read store can greatly increase query performance and application UI responsiveness, especially in distributed scenarios where read-only replicas are located close to the application instances. Bazı veritabanı sistemleri (SQL Server), kullanılabilirliği en üst düzeye çıkarmak için yük devretme çoğaltmaları gibi ek özellikler sağlar.Some database systems (SQL Server) provide additional features such as failover replicas to maximize availability.

Okuma ve yazma depolarının ayrılması, her birinin yüke uygun şekilde ölçeklendirilmesine de imkan sağlar.Separation of the read and write stores also allows each to be scaled appropriately to match the load. Örneğin, okuma depolarının yükü genellikle yazma depolarından çok daha yüksektir.For example, read stores typically encounter a much higher load than write stores.

Sorgu/okuma modeli normalleştirilmişlikten çıkarılmış veriler içeriyorsa (bkz. Gerçekleştirilmiş Görünüm modeli), bir uygulamada her bir görünüm için veriler okunurken veya sistemdeki veriler sorgulanırken performans en üst düzeye çıkar.When the query/read model contains denormalized data (see Materialized View pattern), performance is maximized when reading data for each of the views in an application or when querying the data in the system.

Sorunlar ve dikkat edilmesi gerekenlerIssues and considerations

Bu düzenin nasıl uygulanacağına karar verirken aşağıdaki noktaları göz önünde bulundurun:Consider the following points when deciding how to implement this pattern:

  • Veri deposunun okuma ve yazma işlemleri için ayrı fiziksel depolara bölünmesi sistemin performans ve güvenliğini artırabilir, ancak dayanıklılık ve son tutarlılık açısından karmaşıklığın artmasına da neden olabilir.Dividing the data store into separate physical stores for read and write operations can increase the performance and security of a system, but it can add complexity in terms of resiliency and eventual consistency. Okuma modeli deposunun yazma modeli deposundaki değişiklikleri yansıtacak şekilde güncelleştirilmesi gerekir ve bir kullanıcı eski okuma verilerine dayalı bir istek gönderdiğinde, bu değişikliklerin algılanması zor olabileceğinden işlem tamamlanamayabilir.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, which means that the operation can't be completed.

    Son tutarlılığın açıklaması için bkz. Veri Tutarlılığı Temel Bilgileri.For a description of eventual consistency see the Data Consistency Primer.

  • CQRS modelini yalnızca en çok değer katacağını düşündüğünüz belirli sistem bölümlerine uygulayın.Consider applying CQRS to limited sections of your system where it will be most valuable.

  • Son tutarlılık uygulama konusunda tipik bir yaklaşım, yazma modeli komutların yürütülmesini temel alan salt eklenir bir olay akışı olacak şekilde CQRS ile birlikte olay kaynağı belirleme kullanmaktır.A typical approach to deploying eventual consistency is to use event sourcing in conjunction with CQRS so that the write model is an append-only stream of events driven by execution of commands. Bu olaylar, okuma modeli olarak davranan gerçekleştirilmiş görünümlerin güncelleştirilmesi için kullanılır.These events are used to update materialized views that act as the read model. Daha fazla bilgi için bkz. Olay Kaynağını Belirleme ve CQRS.For more information see Event Sourcing and CQRS.

Bu düzenin kullanılacağı durumlarWhen to use this pattern

Aşağıdaki durumlarda bu modeli kullanın:Use this pattern in the following situations:

  • Aynı veriler üzerinde paralel olarak birden çok işlemin gerçekleştirildiği işbirliğine dayalı etki alanları.Collaborative domains where multiple operations are performed in parallel on the same data. CQRS, aynı türmüş gibi görünen veriler güncelleştirilirken bile etki alanı düzeyinde birleştirme çakışmalarını en aza indirmek (oluşan çakışmalar komutla birleştirilebilir) için yeterli ayrıntı düzeyine sahip komutlar tanımlamanıza imkan sağlar.CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level (any conflicts that do arise can be merged by the command), even when updating what appears to be the same type of data.

  • Karmaşık bir işlem boyunca kullanıcılara bir dizi adımla veya karmaşık etki alanı modelleriyle rehberlik eden görev tabanlı kullanıcı arabirimleri.Task-based user interfaces where users are guided through a complex process as a series of steps or with complex domain models. Etki alanı odaklı tasarım (DDD) tekniklerini zaten bilen ekipler için de kullanışlıdır.Also, useful for teams already familiar with domain-driven design (DDD) techniques. Yazma modeli, modeldeki her bir toplama için tam tutarlılık sağlanması amacıyla iş mantığı, giriş doğrulama ve iş doğrulamasını içeren tam bir komut işleme yığını içerir (veri değişiklikleri için her ilişkili nesne kümesi tek bir birim olarak işlenir).The write model has a full command-processing stack with business logic, input validation, and business validation to ensure that everything is always consistent for each of the aggregates (each cluster of associated objects treated as a unit for data changes) in the write model. Okuma modelinde iş mantığı veya doğrulama yığını yoktur ve yalnızca bir görünüm modelinde kullanılmak üzere bir DTO döndürür.The read model has no business logic or validation stack and just returns a DTO for use in a view model. Okuma modeli, nihai olarak yazma modeliyle tutarlıdır.The read model is eventually consistent with the write model.

  • Veri okuma işlem performansında veri yazma işlemlerinden bağımsız olarak ince ayar yapılmasını gerektiren, özellikle de okuma/yazma oranının çok yüksek olduğu ve yatay ölçeklendirmenin gerektiği senaryolar.Scenarios where performance of data reads must be fine tuned separately from performance of data writes, especially when the read/write ratio is very high, and when horizontal scaling is required. Örneğin, birçok sisteminde okuma işlemlerinin sayısı yazma işlemlerinin sayısından kat kat büyüktür.For example, in many systems the number of read operations is many times greater than the number of write operations. Buna uygun bir model oluşturmak için okuma modelinin ölçeğini genişletip yazma modelini yalnızca bir veya birkaç örnekte çalıştırmayı göz önünde bulundurun.To accommodate this, consider scaling out the read model, but running the write model on only one or a few instances. Yazma modeli örnek sayısının az olması, birleştirme çakışmaları sayısının en aza indirilmesine de yardımcı olur.A small number of write model instances also helps to minimize the occurrence of merge conflicts.

  • Bir geliştirici ekibinin yazma modelinin bir parçası olan karmaşık etki alanı modeline, başka bir ekibin okuma modeline ve kullanıcı arabirimine odaklanabileceği senaryolar.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.

  • Sistemin zamanla gelişmesinin beklendiği ve modelin birden fazla sürümünü içerebildiği ya da iş kurallarının düzenli olarak değiştiği senaryolarda.Scenarios where the system is expected to evolve over time and might contain multiple versions of the model, or where business rules change regularly.

  • Bir alt sistemin geçici olarak başarısız olması durumunda diğerlerinin kullanılabilirlik açısından etkilenme olasılığının düşük olduğu, özellikle de olay kaynağını belirleme ile birlikte diğer sistemlerle tümleştirme gerektiren durumlar.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.

Bu model aşağıdaki durumlarda önerilmez:This pattern isn't recommended in the following situations:

  • Etki alanı veya iş kurallarının basit olduğu durumlar.Where the domain or the business rules are simple.

  • CRUD stili basit bir kullanıcı arabiriminin ve ilgili veri erişim işlemlerinin yeterli olduğu durumlar.Where a simple CRUD-style user interface and the related data access operations are sufficient.

  • Sistem genelinde uygulama için.For implementation across the whole system. Genel bir veri yönetimi senaryosunda CQRS modelinin kullanışlı olabileceği belirli bileşenler vardır, ancak bu modelin zorunlu olmayan durumlarda kullanılması karmaşıklığı önemli ve gereksiz ölçüde artırabilir.There are specific components of an overall data management scenario where CQRS can be useful, but it can add considerable and unnecessary complexity when it isn't required.

Olay Kaynağını Belirleme ve CQRSEvent Sourcing and CQRS

CQRS modeli çoğunlukla Olay Kaynağını Belirleme modeli ile birlikte kullanılır.The CQRS pattern is often used along with the Event Sourcing pattern. CQRS tabanlı sistemler, her biri ilgili görevlere uyarlanmış ve genellikle fiziksel olarak ayrı depolarda bulunan ayrı okuma ve yazma modelleri kullanır.CQRS-based systems use separate read and write data models, each tailored to relevant tasks and often located in physically separate stores. İle kullanıldığında olay kaynağını belirleme düzeni, olayların depo yazma modelidir ve resmi bilgi kaynağı olan.When used with the Event Sourcing pattern, the store of events is the write model, and is the official source of information. CQRS tabanlı bir sistemin okuma modeli, verilerin gerçekleştirilmiş görünümlerini (genellikle yüksek oranda normalleştirilmişlikten çıkarılmış görünümler olarak) sağlar.The read model of a CQRS-based system provides materialized views of the data, typically as highly denormalized views. Bu görünümler uygulamanın arabirimlerine ve görüntüleme gereksinimlerine uyarlandığından, hem görüntüleme hem de sorgu performansının en üst düzeye çıkarılmasına yardımcı olur.These views are tailored to the interfaces and display requirements of the application, which helps to maximize both display and query performance.

Yazma deposu olarak bir noktadaki gerçek veriler yerine olay akışının kullanılması, tek bir toplamada güncelleştirme çakışmaları gerçekleşmesini önler ve performans ile ölçeklenebilirliği en üst düzeye çıkarır.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. Olaylar, okuma deposunun doldurulması için kullanılan gerçekleştirilmiş veri görünümlerinin zaman uyumsuz olarak oluşturulması için kullanılabilir.The events can be used to asynchronously generate materialized views of the data that are used to populate the read store.

Olay deposu resmi bilgi kaynağı olduğundan, sistem geliştiğinde veya okuma modelinin değiştirilmesi gerektiğinde gerçekleştirilmiş görünümlerin silinmesi ve tüm geçmiş olayların yeniden yürütülmesi yoluyla geçerli durumun yeni bir temsilinin oluşturulması mümkündür.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. Gerçekleştirilmiş görünümler aslında dayanıklı bir salt okunur veri önbelleğidir.The materialized views are in effect a durable read-only cache of the data.

CQRS modelini Olay Kaynağını Belirleme modeli ile birlikte kullanırken aşağıdaki noktalara dikkat edin:When using CQRS combined with the Event Sourcing pattern, consider the following:

  • Yazma ve okuma depolarının ayrı olduğu tüm sistemlerde olduğu gibi bu modeli temel alan sistemler yalnızca son tutarlılık sağlar.As with any system where the write and read stores are separate, systems based on this pattern are only eventually consistent. Olayın oluşturulması ile veri deposunun güncelleştirilmesi arasında bir gecikme olur.There will be some delay between the event being generated and the data store being updated.

  • Olayların başlatılması veya işlenmesi ve sorgular ya da bir okuma modeli için gerekli uygun görünümlerin veya nesnelerin derlenmesi ya da güncelleştirilmesi için kod oluşturulması gerektiğinden, bu model karmaşıklığın artmasına neden olur.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. Olay Kaynağını Belirleme modeli ile birlikte kullanılan CQRS modelinin karmaşıklığı, başarılı bir uygulamanın zorlaşmasına yol açabilir ve sistem tasarımı konusunda farklı bir yaklaşım gerektirir.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. Bununla birlikte, olay kaynağını belirleme modeli etki alanının modellenmesini kolaylaştırabilir ve verilerdeki değişikliklerin amacı korunduğundan, görünümleri yeniden oluşturmak ya da yeni görünümler oluşturmak daha kolaydır.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.

  • Belirli varlıklar veya varlık koleksiyonları için olayların yeniden yürütülmesi ve işlenmesi yoluyla okuma modelinde veya veri izdüşümlerinde kullanılmak üzere gerçekleştirilmiş görünümler oluşturmak için gerekli işleme süresi ve kaynak kullanımı önemli bir boyutta olabilir.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. Bu, özellikle de değerlerin uzun dönemler boyunca toplanmasını veya analiz edilmesini gerektiren durumlar (tüm ilişkili olayların incelenmesi gerekebileceğinden) için geçerlidir.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. Bu sorunu çözmek için zamanlanan aralıklarla verilerin anlık görüntülerini (gerçekleşen belirli bir eylemin toplam sayısı veya bir varlığın geçerli durumu gibi) uygulayın.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.

ÖrnekExample

Aşağıdaki kodda, okuma ve yazma modelleri için farklı tanımlar kullanılan örnek bir CQRS uygulamasından alınan bazı bölümler gösterilmiştir.The following code shows some extracts from an example of a CQRS implementation that uses different definitions for the read and the write models. Model arabirimleri temel veri depolarının herhangi bir özelliğe sahip olmasını zorunlu kılmaz ve bu arabirimler ayrı olduğundan, depolar bağımsız olarak geliştirilebilir ve depolarda ince ayar yapılabilir.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şağıdaki kodda okuma modeli tanımı gösterilmiştir.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; }
  }
}

Sistem, kullanıcıların ürünleri derecelendirmesine izin verir.The system allows users to rate products. Uygulama kodu bunu aşağıdaki kodda gösterilen RateProduct komutunu kullanarak yapar.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; }
}

Sistem, uygulama tarafından gönderilen komutları işlemek için ProductsCommandHandler sınıfını kullanır.The system uses the ProductsCommandHandler class to handle commands sent by the application. İstemciler komutları genellikle kuyruk gibi bir mesajlaşma sistemi üzerinden etki alanına gönderir.Clients typically send commands to the domain through a messaging system such as a queue. Komut işleyici bu komutları kabul eder ve etki alanı arabiriminin metotlarını çağırır.The command handler accepts these commands and invokes methods of the domain interface. Her komutun ayrıntı düzeyi, isteklerin çakışma olasılığını azaltmaya yönelik olarak tasarlanır.The granularity of each command is designed to reduce the chance of conflicting requests. Aşağıdaki kodda bir ProductsCommandHandler sınıfının ana hattı gösterilmiştir.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)
  {
    ...
  }
}

Aşağıdaki kodda yazma modelinin IProductsDomain arabirimi gösterilmiştir.The following code shows the IProductsDomain interface from the write model.

public interface IProductsDomain
{
  void AddNewProduct(int id, string name, string description, decimal price);
  void RateProduct(int userId, int rating);
  void AddToInventory(int productId, int quantity);
  void ConfirmItemsShipped(int productId, int quantity);
  void UpdateStockFromInventoryRecount(int productId, int updatedQuantity);
}

Ayrıca, IProductsDomain arabiriminin etki alanında bir anlamı olan yöntemler içerdiğine dikkat edin.Also notice how the IProductsDomain interface contains methods that have a meaning in the domain. CRUD ortamlarında bu metotlar genellikle Save veya Update gibi genel adlara sahip olur ve bağımsız değişken olarak yalnızca bir DTO içerir.Typically, in a CRUD environment these methods would have generic names such as Save or Update, and have a DTO as the only argument. CQRS yaklaşımı, bu kuruluşun iş ve envanter yönetim sistemleri gereksinimlerini karşılayacak şekilde tasarlanabilir.The CQRS approach can be designed to meet the needs of this organization's business and inventory management systems.

Bu model uygulanırken aşağıdaki modeller ve yönergeler kullanışlıdır:The following patterns and guidance are useful when implementing this pattern:

  • CQRS modelinin diğer mimari stilleri ile karşılaştırması için bkz. Mimarisi stilleri ve CQRS mimari stili.For a comparison of CQRS with other architectural styles, see Architecture styles and CQRS architecture style.

  • Veri Tutarlılığı Temel Bilgileri.Data Consistency Primer. SQRS modeli kullanılırken okuma ve yazma veri depoları arasındaki son tutarlılık nedeniyle sık karşılaşılan sorunları ve bunların nasıl çözülebileceğini açıklar.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.

  • Veri Bölümleme Kılavuzu.Data Partitioning Guidance. Ölçeklenebilirliğin geliştirilmesi, çakışmanın azaltılması ve performansın iyileştirilmesi amacıyla CQRS modelinde kullanılan okuma ve yazma veri depolarının nasıl ayrı ayrı yönetilebilen ve erişilebilen bölümlere bölünebileceğini açıklar.Describes how the read and write data stores used in the CQRS pattern can be divided into partitions that can be managed and accessed separately to improve scalability, reduce contention, and optimize performance.

  • Olay Kaynağını Belirleme düzeni.Event Sourcing pattern. Etki alanlarındaki karmaşık görevlerin basitleştirilmesinin yanı sıra performans, ölçeklenebilirlik ve yanıt verme hızının artırılması amacıyla Olay Kaynağını Belirleme modelinin nasıl CQRS modeliyle birlikte kullanılabileceğini açıklar.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. Ayrıca, işlem verilerinde tutarlılık sağlarken telafi eylemlerine olanak tanıyacak tam denetim kayıtlarını ve geçmişini korumanın nasıl mümkün olduğunu gösterir.As well as how to provide consistency for transactional data while maintaining full audit trails and history that can enable compensating actions.

  • Gerçekleştirilmiş Görünüm düzeni.Materialized View pattern. Bir CQRS uygulamasının okuma modeli, yazma modeli verilerinin gerçekleştirilmiş görünümlerini içerebilir ya da gerçekleştirilmiş görünümlerin oluşturulması için okuma modeli kullanılabilir.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.

  • Modeller ve uygulamalar kılavuzu CQRS Gezisi.The patterns & practices guide CQRS Journey. Özellikle, komut sorgu sorumluluğu ayrımı modeline giriş desen ve ne zaman kullanışlı olduğunu açıklar ve Kapanış: Dersler Learned , bu model kullanılırken gündeme sorunlardan bazılarını anlamanıza yardımcı olur.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.

  • Modelle ilgili temel kavramların açıklandığı ve diğer kullanışlı kaynakların bağlantılarının sunulduğu CQRS by Martin Fowler başlıklı gönderi.The post CQRS by Martin Fowler, which explains the basics of the pattern and links to other useful resources.