约定只要本次查询是读写分离的读链接那么就不支持追踪

This commit is contained in:
xuejiaming 2021-12-30 22:14:20 +08:00
parent 4fdb273ead
commit 863ba69a03
6 changed files with 39 additions and 30 deletions

View File

@ -1,9 +1,9 @@
:start :start
::定义版本 ::定义版本
set EFCORE2=2.3.2.07 set EFCORE2=2.3.2.08
set EFCORE3=3.3.2.07 set EFCORE3=3.3.2.08
set EFCORE5=5.3.2.07 set EFCORE5=5.3.2.08
set EFCORE6=6.3.2.07 set EFCORE6=6.3.2.08
::删除所有bin与obj下的文件 ::删除所有bin与obj下的文件
@echo off @echo off

View File

@ -19,12 +19,12 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{ {
ShardingDbContextType = shardingDbContextType; ShardingDbContextType = shardingDbContextType;
ReplaceTables = replaceTables.ToHashSet(); ReplaceTables = replaceTables.ToHashSet();
NoDifferentTail = ReplaceTables.IsEmpty() || ReplaceTables.GroupBy(o => o.Tail).Count() == 1; HasDifferentTail = ReplaceTables.IsNotEmpty() && ReplaceTables.GroupBy(o => o.Tail).Count() != 1;
} }
public ISet<IPhysicTable> ReplaceTables { get; } public ISet<IPhysicTable> ReplaceTables { get; }
public bool NoDifferentTail { get; } public bool HasDifferentTail { get; }
public Type ShardingDbContextType { get; } public Type ShardingDbContextType { get; }
protected bool Equals(TableRouteResult other) protected bool Equals(TableRouteResult other)

View File

@ -13,11 +13,12 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions
public interface IMergeQueryCompilerContext : IQueryCompilerContext public interface IMergeQueryCompilerContext : IQueryCompilerContext
{ {
QueryCombineResult GetQueryCombineResult(); QueryCombineResult GetQueryCombineResult();
IEnumerable<TableRouteResult> GetTableRouteResults(); TableRouteResult[] GetTableRouteResults();
DataSourceRouteResult GetDataSourceRouteResult(); DataSourceRouteResult GetDataSourceRouteResult();
bool IsCrossTable(); bool IsCrossTable();
bool IsCrossDataSource(); bool IsCrossDataSource();
bool IsEnumerableQuery(); bool IsEnumerableQuery();
bool IsParallelQuery();
} }
} }

View File

@ -24,7 +24,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
private readonly IQueryCompilerContext _queryCompilerContext; private readonly IQueryCompilerContext _queryCompilerContext;
private readonly QueryCombineResult _queryCombineResult; private readonly QueryCombineResult _queryCombineResult;
private readonly DataSourceRouteResult _dataSourceRouteResult; private readonly DataSourceRouteResult _dataSourceRouteResult;
private readonly IEnumerable<TableRouteResult> _tableRouteResults; private readonly TableRouteResult[] _tableRouteResults;
/// <summary> /// <summary>
/// 本次查询跨库 /// 本次查询跨库
@ -35,6 +35,10 @@ namespace ShardingCore.Sharding.ShardingExecutors
/// 本次查询跨表 /// 本次查询跨表
/// </summary> /// </summary>
private readonly bool _isCrossTable; private readonly bool _isCrossTable;
/// <summary>
/// 存在一次查询跨多个tail
/// </summary>
private readonly bool _existCrossTableTails;
private QueryCompilerExecutor _queryCompilerExecutor; private QueryCompilerExecutor _queryCompilerExecutor;
@ -45,9 +49,10 @@ namespace ShardingCore.Sharding.ShardingExecutors
_queryCombineResult = queryCombineResult; _queryCombineResult = queryCombineResult;
_parallelTableManager = (IParallelTableManager)ShardingContainer.GetService(typeof(IParallelTableManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType())); _parallelTableManager = (IParallelTableManager)ShardingContainer.GetService(typeof(IParallelTableManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
_dataSourceRouteResult = dataSourceRouteResult; _dataSourceRouteResult = dataSourceRouteResult;
_tableRouteResults = GetTableRouteResults(tableRouteResults); _tableRouteResults = GetTableRouteResults(tableRouteResults).ToArray();
_isCrossDataSource = dataSourceRouteResult.IntersectDataSources.Count > 1; _isCrossDataSource = dataSourceRouteResult.IntersectDataSources.Count > 1;
_isCrossTable = _tableRouteResults.Count() > 1|| _tableRouteResults.IsNotEmpty()&& !_tableRouteResults.First().NoDifferentTail; _isCrossTable = _tableRouteResults.Count() > 1;
_existCrossTableTails = _tableRouteResults.Any(o => o.HasDifferentTail);
} }
private IEnumerable<TableRouteResult> GetTableRouteResults(IEnumerable<TableRouteResult> tableRouteResults) private IEnumerable<TableRouteResult> GetTableRouteResults(IEnumerable<TableRouteResult> tableRouteResults)
@ -113,11 +118,12 @@ namespace ShardingCore.Sharding.ShardingExecutors
} }
else else
{ {
hasQueryCompilerExecutor = IsSingleDbContextNativeQuery(); hasQueryCompilerExecutor = IsSingleQuery();
if (hasQueryCompilerExecutor.Value) if (hasQueryCompilerExecutor.Value&&(!IsQueryTrack()||!_existCrossTableTails))
{ {
//要么本次查询不追踪如果需要追踪不可以存在跨tails
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>(); var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), !IsQueryTrack() || CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First())); var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), IsParallelQuery(), routeTailFactory.Create(_tableRouteResults[0]));
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression()); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
} }
} }
@ -132,7 +138,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
return _queryCombineResult; return _queryCombineResult;
} }
public IEnumerable<TableRouteResult> GetTableRouteResults() public TableRouteResult[] GetTableRouteResults()
{ {
return _tableRouteResults; return _tableRouteResults;
} }
@ -145,20 +151,9 @@ namespace ShardingCore.Sharding.ShardingExecutors
/// 既不可以跨库也不可以跨表,所有的分表都必须是相同后缀才可以 /// 既不可以跨库也不可以跨表,所有的分表都必须是相同后缀才可以
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private bool IsSingleDbContextNativeQuery() private bool IsSingleQuery()
{ {
return !_isCrossDataSource&&!_isCrossTable && (!IsQueryTrack()|| OnlyShardingDataSourceOrNoDifferentTail()); return !_isCrossDataSource&&!_isCrossTable;
}
/// <summary>
/// 不存在分表或者分了但是都是一样的tail并且没有不分表的对象
/// </summary>
/// <returns></returns>
private bool OnlyShardingDataSourceOrNoDifferentTail()
{
if (GetQueryEntities().All(o => GetEntityMetadataManager().IsOnlyShardingDataSource(o)))
return true;
var firstTableRouteResult = _tableRouteResults.First();
return (firstTableRouteResult.NoDifferentTail&&GetQueryEntities().All(o=>GetEntityMetadataManager().IsShardingTable(o)));
} }
public bool IsCrossTable() public bool IsCrossTable()
@ -175,5 +170,13 @@ namespace ShardingCore.Sharding.ShardingExecutors
{ {
return _queryCompilerContext.IsEnumerableQuery(); return _queryCompilerContext.IsEnumerableQuery();
} }
/// <summary>
/// 如果需要聚合并且存在跨tail的查询或者本次是读链接
/// </summary>
/// <returns></returns>
public bool IsParallelQuery()
{
return _isCrossTable || _existCrossTableTails|| CurrentQueryReadConnection();
}
} }
} }

View File

@ -28,6 +28,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
private QueryCompilerExecutor _queryCompilerExecutor; private QueryCompilerExecutor _queryCompilerExecutor;
private bool? hasQueryCompilerExecutor; private bool? hasQueryCompilerExecutor;
private bool? _isNoTracking; private bool? _isNoTracking;
private readonly bool _currentQueryReadConnection;
private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression) private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression)
{ {
@ -39,6 +40,8 @@ namespace ShardingCore.Sharding.ShardingExecutors
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType)); _entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
_shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType); _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType);
_currentQueryReadConnection =
_shardingConfigOption.UseReadWrite && _shardingDbContext.CurrentIsReadWriteSeparation();
} }
public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression) public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression)
@ -73,7 +76,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
public bool CurrentQueryReadConnection() public bool CurrentQueryReadConnection()
{ {
return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation(); return _currentQueryReadConnection;
} }
public bool IsQueryTrack() public bool IsQueryTrack()

View File

@ -228,12 +228,12 @@ namespace ShardingCore.Sharding
} }
/// <summary> /// <summary>
/// 是否使用并行查询 /// 是否使用并行查询仅分库无所谓可以将分库的当前DbContext进行储存起来但是分表就不行因为一个DbContext最多一对一表
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool IsParallelQuery() public bool IsParallelQuery()
{ {
return MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.CurrentQueryReadConnection(); return MergeQueryCompilerContext.IsParallelQuery();
} }
/// <summary> /// <summary>
@ -244,6 +244,8 @@ namespace ShardingCore.Sharding
{ {
if (!IsParallelQuery()) if (!IsParallelQuery())
return false; return false;
if (MergeQueryCompilerContext.CurrentQueryReadConnection())
return false;
return QueryTrack() && _trackerManager.EntityUseTrack(entityType); return QueryTrack() && _trackerManager.EntityUseTrack(entityType);
} }
private bool QueryTrack() private bool QueryTrack()