CQRS:同步写入和读取数据库

时间:2010-07-13 07:02:46

标签: cqrs

任何人都可以就各种方式给我一些指导 同步写入和读取数据库?

有哪些不同的技术,以及如何评估每种技术 可行性,绩效,实施成本等等。

3 个答案:

答案 0 :(得分:7)

通常在CQRS中,写入DB用于存储长期运行的流程(sagas)的过渡数据。如果你正在同步读写DB(我假设你的意思是两种方式),你可能会做错事。

对于服务需要多条消息的长时间运行进程,它需要一种在所有消息到达之前临时存储数据的方法。这方面的一个例子是客户注册,其中需要经理批准,需要一周的时间来处理。该服务需要一种在批准到达之前临时存储客户信息的方法。这是写DB用于存储这段临时数据的地方。请注意,在客户获得批准之前,尚未向读取数据库写入任何内容。

当批准最终到达时,服务将从写入DB获取客户信息,完成注册过程并将其写入读取DB。此时,写入DB中的临时客户信息已完成其工作,可以从写入DB中删除。请注意,没有涉及任何双向同步。

对于更简单的流程(例如更改客户名称),可以立即将更改写入读取的数据库。不需要写入写入DB,因为在这种情况下没有临时数据。

答案 1 :(得分:1)

如果您像我一样将read store视为Query服务使用的db(及其非规范化) 并且写入db作为存储域事件的数据库,然后如果您需要将它们同步到特定时刻,那么您可以做的只是重放已存储的事件。 如果您希望尽可能保持最新状态,则无需按版本限制

如果您正在使用CQRS,那么您可能会拥有一个看起来有点像

的存储库
    public interface IRepository<T> where T : AggregateRoot, new()
    {
        void Save(AggregateRoot aggregate, int expectedVersion);
        T GetById(Guid id);
        T GetById(Guid id, int version);
    }

希望这会有所帮助 干杯

答案 2 :(得分:0)

查询模型不需要一致..它需要最终一致。查询模型也是视图模型,即表已根据用户界面的要求加入。所以你甚至可以使用内存缓存,或者像Redis一样 命令端就像命令对象,它包含更新数据库的所有相关信息。这些对象可能会填满消息队列。命令对象由命令处理器处理,命令处理器以事务方式更新查询缓存和写入数据库。写数据库可以是RDBMS ..但很明显,应该像MongoDB一样进行写优化 您也可以通过消息传递系统更新读取数据库 一些用于此目的的良好消息传递系统是RabbitMQ和0MQ。