通過一些調整和優化,4.3已經運行在生產環境,對於不久將會遇到的查詢性能,讀寫分離需求列上日程sql
對於一個數據庫做了主從發佈/訂閱,主庫爲DB1,從庫爲DB2數據庫
全部寫入經過DB1,全部查詢經過DB2,固然也能夠經過DB1性能
在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方法將此標記傳到數據訪問對象建立層this
在程序啓動處,以Global爲例spa
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 }
這樣就實現了在邏輯調用上實現了讀寫分離code
啓用主從讀寫分離orm
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
最新源碼見文章底部簽名