CRL快速开发框架4.4版发布,支持主从读写分离

时间:2023-03-09 14:15:31
CRL快速开发框架4.4版发布,支持主从读写分离

经过一些调整和优化,4.3已经运行在生产环境,对于不久将会遇到的查询性能,读写分离需求列上日程

读写分离需求

对于一个数据库作了主从发布/订阅,主库为DB1,从库为DB2

所有写入通过DB1,所有查询通过DB2,当然也可以通过DB1

CRL内部实现

在CRL内部调用,请求读和请求写的方法会标记为Read或Write,然后再通过标记实现不同的数据库连接访问对象

如以下代码

 /// <summary>
/// 返回动态对象的查询
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
internal CallBackDataReader GetQueryDynamicReader(LambdaQueryBase query)
{
CheckTableCreated(query.__MainType);
var sql = "";
query.FillParames(this);
sql = query.GetQuery();
sql = _DBAdapter.SqlFormat(sql);
System.Data.Common.DbDataReader reader;
var compileSp = query.__CompileSp;
var db = GetDBHelper(AccessType.Read);
if (!compileSp)
{
if (query.TakeNum > )
{
db.AutoFormatWithNolock = false;
}
reader = db.ExecDataReader(sql);
}
else//生成储过程
{
string sp = CompileSqlToSp(_DBAdapter.TemplateSp, sql);
reader = db.RunDataReader(sp);
}
query.ExecuteTime = db.ExecuteTime;
ClearParame();
return new CallBackDataReader(reader, null, sql);
}

GetDBHelper方法将此标记传到数据访问对象创建层

在程序启动处,以Global为例

 protected void Application_Start(object sender, EventArgs e)
{
CRL.SettingConfig.UseReadSeparation = true;//启用主从读写分离
//配置数据连接
CRL.SettingConfig.GetDbAccess = (dbLocation) =>
{
var obj = dbLocation.TagData;
if (dbLocation.ShardingDataBase != null)//按分库判断
{
if (dbLocation.ShardingDataBase.Name == "db1")
{
return WebTest.Code.LocalSqlHelper.TestConnection;
}
else
{
return WebTest.Code.LocalSqlHelper.TestConnection2;
}
}
else
{
//可按type区分数据库
var type2 = dbLocation.ManageType;
if (type2 == typeof(Code.MongoDBTestManage))
{
return Code.LocalSqlHelper.MongoDB;
}
if(dbLocation.AccessType== CRL.AccessType.Read)//区分读写
{
return Code.LocalSqlHelper.TestConnection2;
}
return WebTest.Code.LocalSqlHelper.TestConnection;
}
}; }

这样就实现了在逻辑调用上实现了读写分离

实际调用

启用主从读写分离

CRL.SettingConfig.UseReadSeparation = true;

更改数据

var item = Code.ProductDataManage.Instance.QueryItem();
item.ProductName = "更改主库数据为" + DateTime.Now.Second;
Code.ProductDataManage.Instance.Update(item);

DB1数据被更改

查询数据

 var item = Code.ProductDataManage.Instance.QueryItem();
Response.Write("从库数据2为" + item.ProductName);

查询出DB2的数据

CRL快速开发框架4.4版发布,支持主从读写分离

事务问题

由于主从复制可能存在延迟,在事务中可不想查到脏数据,或者数据在事务中被更改

因此,在事务内需要由主库查询

在CRL事务范围内的查询,都默认为主库

此功能测试代码见文档/Page/ReadSeparation.aspx

最新源码见文章底部签名