1. 程式人生 > >CRL快速開發框架4.4版發布,支持主從讀寫分離

CRL快速開發框架4.4版發布,支持主從讀寫分離

需求 生產 由於 logs else gety img 分離 dap

經過一些調整和優化,4.3已經運行在生產環境,對於不久將會遇到的查詢性能,讀寫分離需求列上日程

讀寫分離需求

對於一個數據庫作了主從發布/訂閱,主庫為DB1,從庫為DB2

所有寫入通過DB1,所有查詢通過DB2,當然也可以通過DB1

CRL內部實現

在CRL內部調用,請求讀和請求寫的方法會標記為Read或Write,然後再通過標記實現不同的數據庫連接訪問對象

如以下代碼

 1 /// <summary>
 2         /// 返回動態對象的查詢
 3         /// </summary>
 4         /// <param name="query"></param>
5 /// <returns></returns> 6 internal CallBackDataReader GetQueryDynamicReader(LambdaQueryBase query) 7 { 8 CheckTableCreated(query.__MainType); 9 var sql = ""; 10 query.FillParames(this); 11 sql = query.GetQuery();
12 sql = _DBAdapter.SqlFormat(sql); 13 System.Data.Common.DbDataReader reader; 14 var compileSp = query.__CompileSp; 15 var db = GetDBHelper(AccessType.Read); 16 if (!compileSp) 17 { 18 if (query.TakeNum > 0) 19
{ 20 db.AutoFormatWithNolock = false; 21 } 22 reader = db.ExecDataReader(sql); 23 } 24 else//生成儲過程 25 { 26 string sp = CompileSqlToSp(_DBAdapter.TemplateSp, sql); 27 reader = db.RunDataReader(sp); 28 } 29 query.ExecuteTime = db.ExecuteTime; 30 ClearParame(); 31 return new CallBackDataReader(reader, null, sql); 32 }

GetDBHelper方法將此標記傳到數據訪問對象創建層

在程序啟動處,以Global為例

 1 protected void Application_Start(object sender, EventArgs e)
 2         {
 3             CRL.SettingConfig.UseReadSeparation = true;//啟用主從讀寫分離
 4             //配置數據連接
 5             CRL.SettingConfig.GetDbAccess = (dbLocation) =>
 6             {
 7                 var obj = dbLocation.TagData;
 8                 if (dbLocation.ShardingDataBase != null)//按分庫判斷
 9                 {
10                     if (dbLocation.ShardingDataBase.Name == "db1")
11                     {
12                         return WebTest.Code.LocalSqlHelper.TestConnection;
13                     }
14                     else
15                     {
16                         return WebTest.Code.LocalSqlHelper.TestConnection2;
17                     }
18                 }
19                 else
20                 {
21                     //可按type區分數據庫
22                     var type2 = dbLocation.ManageType;
23                     if (type2 == typeof(Code.MongoDBTestManage))
24                     {
25                         return Code.LocalSqlHelper.MongoDB;
26                     }
27                     if(dbLocation.AccessType== CRL.AccessType.Read)//區分讀寫
28                     {
29                         return Code.LocalSqlHelper.TestConnection2;
30                     }
31                     return WebTest.Code.LocalSqlHelper.TestConnection;
32                 }
33             };
34 
35         }

這樣就實現了在邏輯調用上實現了讀寫分離

實際調用

啟用主從讀寫分離

CRL.SettingConfig.UseReadSeparation = true;

更改數據

var item = Code.ProductDataManage.Instance.QueryItem(2);
item.ProductName = "更改主庫數據為" + DateTime.Now.Second;
Code.ProductDataManage.Instance.Update(item);

DB1數據被更改

查詢數據

 var item = Code.ProductDataManage.Instance.QueryItem(2);
            Response.Write("從庫數據2為" + item.ProductName);

查詢出DB2的數據

技術分享

事務問題

由於主從復制可能存在延遲,在事務中可不想查到臟數據,或者數據在事務中被更改

因此,在事務內需要由主庫查詢

在CRL事務範圍內的查詢,都默認為主庫

此功能測試代碼見文檔/Page/ReadSeparation.aspx

最新源碼見文章底部簽名

CRL快速開發框架4.4版發布,支持主從讀寫分離