微服務實戰(六):落地微服務架構到直銷系統(事件存儲)

在CQRS架構中,一個比較重要的內容就是當命令處理器從命令隊列中接收到相關的命令數據后,通過調用領域對象邏輯,然后將當前事件的對象數據持久化到事件存儲中。主要的用途是能夠快速持久化對象此次的狀態,另外也可以通過未來最終一致性的需求,通過事件數據將對象還原到一個特定的狀態,這個狀態通常是通過對象事件的版本來進行還原的。

要實現一個事件存儲的框架,我們通常需要實現以下幾個方面:

clipboard.png

1.對象事件的存儲表

我們通常將對象某個變化的事件數據存儲到數據庫的表中,通常采用關系型數據庫進行存儲,這里使用SQL Server。

clipboard.png

AggregationRootId是當前聚合根對象的Id;AssemblyQualifiedAggreateRooType是當前聚合根對象的FQDN名,在C#代碼中對應名稱空間+類名(例如:Order.Domain.POCOModels.Orders, Order.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null);AssemblyQualifiedCommandAndEventType是操作當前聚合根的事件類型的FQDN名字,在C#代碼中對應名稱空間+類名(例如:Events.OrderCommands.CreateOrderCommand, Events, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null),Version對應的是針對某個聚合根當前事件操作的版本,通常對一個聚合根進行操作,版本就加1,Data則包括當前事件操作后,對象的當前狀態數據。

2.重構Event用以支持存儲

前面文章實現的事件只是用于標識消息,在事件需要存儲時,我們需要更多的屬性,包括聚合根ID,聚合根類型,操作聚合根的事件類型,版本號等。

public interface IEvent

{Guid Id { get; set; }DateTime CreateDate { get; set; }Guid AggregationRootId { get; set; }string AssemblyQualifiedAggreateRooType { get; set; }string AssemblyQualifiedCommandAndEventType { get; set; }int Version { get; set; }
}

public class BaseEvent : IEvent

{public Guid Id { get; set; }public DateTime CreateDate { get; set; }public Guid AggregationRootId { get; set; }public string AssemblyQualifiedAggreateRooType { get; set; }public string AssemblyQualifiedCommandAndEventType { get; set; }public int Version { get; set; }public BaseEvent(){this.Id = Guid.NewGuid();this.CreateDate = DateTime.Now;}
}

3.實現存儲的事件對象

其實這里要實現的就是將事件和事件對象之間做相互的轉換,用于未來存儲事件或將事件反序列化成事件對象進行使用。

public class EventObject:BaseEvent

{        public byte[] Data { get; set; }public static EventObject FromDomainEvent(IEvent idomainevent){var domaineventobject = new EventObject();domaineventobject.Id = idomainevent.Id;domaineventobject.CreateDate = idomainevent.CreateDate;domaineventobject.Version = idomainevent.Version;domaineventobject.AggregationRootId = idomainevent.AggregationRootId;domaineventobject.AssemblyQualifiedAggreateRooType = idomainevent.AssemblyQualifiedAggreateRooType;domaineventobject.AssemblyQualifiedCommandAndEventType = idomainevent.AssemblyQualifiedCommandAndEventType;domaineventobject.Data = XmlObjectSerializer.Serialize(idomainevent);return domaineventobject;}public  IEvent ToDomainEvent(){            Type type = Type.GetType(this.AssemblyQualifiedAggreateRooType);var domainevent = (IEvent)XmlObjectSerializer.Deserialize(type, this.Data);domainevent.Id = this.Id;return domainevent;}
}

FromDomainEvent方法就是將事件信息轉換為以后要存儲的事件對象,ToDomainEvent就是將事件對象轉換為事件。

4.實現事件存儲

實現事件存儲就是將領域事件對象存儲到我們前面創建的數據庫表中。為了能夠快速存儲,我們并不采用ORM框架,而是直接使用ADO.NET完成事件對象的存儲。

public void SaveEvent(IEvent idomainevent)

    {try{var domaineventobject = EventObject.FromDomainEvent(idomainevent);conn.Open();SqlParameter sqlparm = new SqlParameter("@AggregationRootId", System.Data.SqlDbType.UniqueIdentifier);sqlparm.Value = idomainevent.AggregationRootId;cmd =new SqlCommand("select count(*) from DomainCommandAndEventObject where AggregationRootId=@AggregationRootId", conn);cmd.Parameters.Add(sqlparm);var count = cmd.ExecuteScalar();if(count!=null){domaineventobject.Version = int.Parse(count.ToString());}SqlParameter[] sqlparams = new SqlParameter[7];sqlparams[0] = new SqlParameter("@Id", System.Data.SqlDbType.UniqueIdentifier);sqlparams[0].Value = domaineventobject.Id;sqlparams[1] = new SqlParameter("@AggregationRootId", System.Data.SqlDbType.UniqueIdentifier);sqlparams[1].Value = domaineventobject.AggregationRootId;sqlparams[2] = new SqlParameter("@AssemblyQualifiedAggreateRooType", System.Data.SqlDbType.NVarChar);sqlparams[2].Value = domaineventobject.AssemblyQualifiedAggreateRooType;sqlparams[3] = new SqlParameter("@AssemblyQualifiedCommandAndEventType", System.Data.SqlDbType.NVarChar);sqlparams[3].Value = domaineventobject.AssemblyQualifiedCommandAndEventType;sqlparams[4] = new SqlParameter("@CreateDate", System.Data.SqlDbType.DateTime);sqlparams[4].Value = domaineventobject.CreateDate;sqlparams[5] = new SqlParameter("@Version", System.Data.SqlDbType.Int);sqlparams[5].Value = domaineventobject.Version;sqlparams[6] = new SqlParameter("@Data", System.Data.SqlDbType.VarBinary);sqlparams[6].Value = domaineventobject.Data;cmd = new SqlCommand("insert DomainCommandAndEventObject values(@Id,@AggregationRootId,@AssemblyQualifiedAggreateRooType,@AssemblyQualifiedCommandAndEventType,@CreateDate,@Version,@Data)", conn);foreach(var sqlparam in sqlparams){cmd.Parameters.Add(sqlparam);}cmd.ExecuteNonQuery();}catch(Exception error){throw error;}finally{cmd.Dispose();conn.Close();}

這樣,我們基本就實現了事件與存儲方面的基礎內容。

QQ討論群:309287205
微服務實戰視頻請關注微信公眾號:MSSHCJ

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389761.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389761.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389761.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

時間序列數據的多元回歸_清理和理解多元時間序列數據

時間序列數據的多元回歸No matter what kind of data science project one is assigned to, making sense of the dataset and cleaning it always critical for success. The first step is to understand the data using exploratory data analysis (EDA)as it helps us crea…

vue-cli搭建項目的目錄結構及說明

vue-cli基于webpack搭建項目的目錄結構 build文件夾 ├── build // 項目構建的(webpack)相關代碼 │ ├── build.js // 生產環境構建代碼(在npm run build的時候會用到這個文件夾)│ ├── check-versions.js // 檢查node&am…

391. 完美矩形

391. 完美矩形 給你一個數組 rectangles ,其中 rectangles[i] [xi, yi, ai, bi] 表示一個坐標軸平行的矩形。這個矩形的左下頂點是 (xi, yi) ,右上頂點是 (ai, bi) 。 如果所有矩形一起精確覆蓋了某個矩形區域,則返回 true ;否…

bigquery 教程_bigquery挑戰實驗室教程從數據中獲取見解

bigquery 教程This medium article focusses on the detailed walkthrough of the steps I took to solve the challenge lab of the Insights from Data with BigQuery Skill Badge on the Google Cloud Platform (Qwiklabs). I got access to this lab in the Google Cloud R…

學習linux系統到底有沒捷徑?

2019獨角獸企業重金招聘Python工程師標準>>> 說起linux操作系,可能對于很多不了解的人來說,第一個想到的就是類似于黑客帝國中的黑框框以及一串串不知所云的代碼,總之這些感覺都可以總結成為一個字,那就是——酷&#…

機器學習之路:python k近鄰回歸 預測波士頓房價

python3 學習機器學習api 使用兩種k近鄰回歸模型 分別是 平均k近鄰回歸 和 距離加權k近鄰回歸 進行預測 git: https://github.com/linyi0604/MachineLearning 代碼: 1 from sklearn.datasets import load_boston2 from sklearn.cross_validation import train_test_…

大話數據結構 (程杰 著)

1轉載于:https://www.cnblogs.com/revoid/p/9605734.html

wxpython實現界面跳轉

wxPython實現Frame之間的跳轉/更新的一種方法 wxPython是Python中重要的GUI框架,下面通過自己的方法實現模擬類似PC版微信登錄,并跳轉到主界面(朋友圈)的流程。 (一)項目目錄 【說明】 icon : 保存項目使用…

java職業技能了解精通_如何通過精通數字分析來提升職業生涯的發展,第8部分...

java職業技能了解精通Continuing from the seventh article in this series, we are going to explore ways to present data. Over the past few years, Marketing and SEO field has become more data-driven than in the past thanks to tools like Google Webmaster Tools …

2028. 找出缺失的觀測數據

2028. 找出缺失的觀測數據 現有一份 n m 次投擲單個 六面 骰子的觀測數據,骰子的每個面從 1 到 6 編號。觀測數據中缺失了 n 份,你手上只拿到剩余 m 次投擲的數據。幸好你有之前計算過的這 n m 次投擲數據的 平均值 。 給你一個長度為 m 的整數數組 …

51nod 1250 排列與交換——dp

題目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId1250 仔細思考dp。 第一問,考慮已知 i-1 個數有多少種方案。再放入一個數,它是最大的且在最后面,所以它的位置不同的話,就是不同的方案。它在特定…

BZOJ.1024.[SCOI2009]生日快樂(記憶化搜索)

題目鏈接 搜索,枚舉切的n-1刀。 對于長n寬m要切x刀,可以劃分為若干個 長n寬m要切x刀 的子問題,對所有子問題的答案取max 對所有子問題的方案取min 就是當前狀態答案。 這顯然是會有很多重復狀態的,用map記憶化(長寬都是double)。 …

kfc流程管理炸薯條幾秒_炸薯條成為數據科學的最后前沿

kfc流程管理炸薯條幾秒In February, our Data Science team had an argument about which restaurant we went to made the best French Fry.2月,我們的數據科學團隊對我們去哪家餐廳做得最好的炸薯條產生了爭議。 We decided to make it a competition throughout…

XSS理解與防御

一、說明 我說我不理解為什么別人做得出來我做不出來,比如這里要說的XSS我覺得很多人就不了解其定義和原理的,在不了解定義和原理的背景下他們可以拿站,這讓人怎么理解呢。那時我最怕兩個問題,第一個是題目做得怎么樣第二個是你能…

Java大數

轉自:https://www.cnblogs.com/zufezzt/p/4794271.html import java.util.*; import java.math.*; public class Main{public static void main(String args[]){Scanner cin new Scanner(System.in);BigInteger a, b;//以文件EOF結束while (cin.hasNext()){a cin.…

2027. 轉換字符串的最少操作次數

2027. 轉換字符串的最少操作次數 給你一個字符串 s ,由 n 個字符組成,每個字符不是 ‘X’ 就是 ‘O’ 。 一次 操作 定義為從 s 中選出 三個連續字符 并將選中的每個字符都轉換為 ‘O’ 。注意,如果字符已經是 ‘O’ ,只需要保持…

bigquery_到Google bigquery的sql查詢模板,它將您的報告提升到另一個層次

bigqueryIn this post, we’re sharing report templates that you can build with SQL queries to Google BigQuery data.在本文中,我們將分享您可以使用SQL查詢為Google BigQuery數據構建的報告模板。 First, you’ll find out about what you can calculate wit…

分類樹/裝袋法/隨機森林算法的R語言實現

原文首發于簡書于[2018.06.12] 本文是我自己動手用R語言寫的實現分類樹的代碼,以及在此基礎上寫的袋裝法(bagging)和隨機森林(random forest)的算法實現。全文的結構是: 分類樹 基本知識predginisplitrules…

數據科學學習心得_學習數據科學時如何保持動力

數據科學學習心得When trying to learn anything all by yourself, it is easy to lose motivation and get thrown off track.嘗試自己學習所有東西時,很容易失去動力并偏離軌道。 In this article, I will provide you with some tips that I used to stay focus…

用php當作cat使用

今天,本來是想敲 node test.js 執行一下,test.js文件,結果 慣性的敲成了 php test.js, 原文輸出了 test.js的內容。 突然覺得,這東西 感覺好像是 cat 命令,嘿嘿,以后要是ubuntu 上沒裝 cat , …