CQRS(Command Query Responsibility Segregation),一种奇怪的开发体验,除了频繁的切换文件夹,但整个业务思路是非常清晰的的。
一、什么是CQRS
在CQRS中,C (Command) 是用来进行CUD的,Q (Query)则是对应查询。
每一个Command都必然改变对象的状态,且不会有任何返回。
每一个Query都不改变对象状态,而是返回结果。
根据CQS的思想,然后一个方法都可以分离出命令和查询。
// 命令
private void IncreaseCommand(int value) { i += value; }
// 查询 private int QueryValue() { return i; }
二、传统的CRUD问题
1、使用同一个对象实体来进行数据库读写可能会太粗糙,大多数情况下,比如编辑的时候可能只需要更新个别字段,但是却需要将整个对象都穿进去,有些字段其实是不需要更新的。在查询的时候在表现层可能只需要个别字段,但是需要查询和返回整个实体对象。
2、使用同一实体对象对同一数据进行读写操作的时候,可能会遇到资源竞争的情况,经常要处理的锁的问题,在写入数据的时候,需要加锁。读取数据的时候需要判断是否允许脏读。这样使得系统的逻辑性和复杂性增加,并且会对系统吞吐量的增长会产生影响。
3、同步的,直接与数据库进行交互在大数据量同时访问的情况下可能会影响性能和响应性,并且可能会产生性能瓶颈。
4、由于同一实体对象都会在读写操作中用到,所以对于安全和权限的管理会变得比较复杂。
在实际业务中,数据库通成都是读比例远远高于写比例。所以一般情况下,会使用主库进行CUD,从库R,但这种情况是从数据库视角进行读写分离,而CQRS是从业务上面进行分离的。
三、CQRS的问题
入下图所示,这种形式是通过事件把同步变为异步,也就没有并发代理的一些列问题。
但也是这个原因,因此这种方式必须是异步的。
所以采用中介者可以解决这种问题。下面的例子中,将使用MediatoR作为作为事件总线核心。
事件总线:连接一切事件的地方,内部知道每个事件由谁触发和由谁处理,大型中介所?
写一个简单的例子体验下CQRS