优化模型缓存
This commit is contained in:
parent
bee07e9ec2
commit
3a1616918b
|
@ -89,6 +89,7 @@ namespace Sample.AutoCreateIfPresent
|
|||
public override void Configure(EntityMetadataTableBuilder<AreaDevice> builder)
|
||||
{
|
||||
builder.ShardingProperty(o => o.Area);
|
||||
builder.TableSeparator(string.Empty);
|
||||
}
|
||||
|
||||
public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.MySql.DbContexts;
|
||||
using Sample.MySql.Domain.Entities;
|
||||
|
@ -91,6 +92,19 @@ namespace Sample.MySql.Controllers
|
|||
// .Where(o => o.Id == "2").FirstOrDefaultAsync();
|
||||
// _defaultTableDbContext.Update(resultX123);
|
||||
// _defaultTableDbContext.SaveChanges();
|
||||
Stopwatch sp = Stopwatch.StartNew();
|
||||
var sysUserMods = await _defaultTableDbContext.Set<SysUserMod>().ToListAsync();
|
||||
sp.Stop();
|
||||
Console.WriteLine(sp.ElapsedMilliseconds);
|
||||
sp.Restart();
|
||||
var sysUserMods11 = await _defaultTableDbContext.Set<SysUserMod>().AsNoTracking().ToListAsync();
|
||||
sp.Stop();
|
||||
Console.WriteLine(sp.ElapsedMilliseconds);
|
||||
sp.Restart();
|
||||
var sysUserMods22 = await _defaultTableDbContext.Set<SysUserMod>().ToListAsync();
|
||||
sp.Stop();
|
||||
Console.WriteLine(sp.ElapsedMilliseconds);
|
||||
|
||||
var resultX1 = await _defaultTableDbContext.Set<SysUserMod>()
|
||||
.Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name })
|
||||
.Select(o => new
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Sample.MySql.Domain.Entities;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
|
|
|
@ -104,6 +104,8 @@ namespace Sample.MySql
|
|||
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
|
||||
}).UseConfig((sp,o) =>
|
||||
{
|
||||
o.CacheModelLockConcurrencyLevel = 31;
|
||||
o.CheckShardingKeyValueGenerated = false;
|
||||
var loggerFactory1= sp.GetService<ILoggerFactory>();
|
||||
var loggerFactory2 = sp.ApplicationServiceProvider.GetService<ILoggerFactory>();
|
||||
// o.UseEntityFrameworkCoreProxies = true;
|
||||
|
@ -111,18 +113,18 @@ namespace Sample.MySql
|
|||
o.AutoUseWriteConnectionStringAfterWriteDb = true;
|
||||
o.UseShardingQuery((conStr, builder) =>
|
||||
{
|
||||
builder.UseMySql(conStr, new MySqlServerVersion(new Version()))
|
||||
builder.UseMySql(conStr, new MySqlServerVersion(new Version()));
|
||||
// .UseLoggerFactory(efLogger)
|
||||
// .EnableSensitiveDataLogging()
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
||||
//.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
||||
});
|
||||
o.UseShardingTransaction((connection, builder) =>
|
||||
{
|
||||
builder
|
||||
.UseMySql(connection, new MySqlServerVersion(new Version()))
|
||||
.UseMySql(connection, new MySqlServerVersion(new Version()));
|
||||
// .UseLoggerFactory(efLogger)
|
||||
// .EnableSensitiveDataLogging()
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
||||
//.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
||||
});
|
||||
o.AddDefaultDataSource("ds0",
|
||||
"server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
|
||||
|
|
|
@ -13,6 +13,8 @@ using System.Diagnostics;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails;
|
||||
using ShardingCore.Extensions;
|
||||
|
@ -70,7 +72,7 @@ namespace Sample.SqlServer
|
|||
{
|
||||
builder.AddConsole();
|
||||
}));
|
||||
}).AddShardingCore();
|
||||
}).ReplaceService<ILoggerFactory,NullLoggerFactory>().AddShardingCore();
|
||||
//services.AddShardingDbContext<DefaultShardingDbContext1>(
|
||||
// (conn, o) =>
|
||||
// o.UseSqlServer(conn).UseLoggerFactory(efLogger)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Exceptions;
|
||||
|
||||
namespace ShardingCore.Core.ModelCacheLockerProviders
|
||||
{
|
||||
public class DefaultModelCacheLockerProvider:IModelCacheLockerProvider
|
||||
{
|
||||
private readonly ShardingConfigOptions _shardingConfigOptions;
|
||||
private readonly List<object> _locks;
|
||||
|
||||
public DefaultModelCacheLockerProvider(ShardingConfigOptions shardingConfigOptions)
|
||||
{
|
||||
_shardingConfigOptions = shardingConfigOptions;
|
||||
if (shardingConfigOptions.CacheModelLockConcurrencyLevel <= 0)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{shardingConfigOptions.CacheModelLockConcurrencyLevel} should > 0");
|
||||
}
|
||||
|
||||
_locks = new List<object>(shardingConfigOptions.CacheModelLockConcurrencyLevel);
|
||||
for (int i = 0; i < shardingConfigOptions.CacheModelLockConcurrencyLevel; i++)
|
||||
{
|
||||
_locks.Add(new object());
|
||||
}
|
||||
}
|
||||
public object GetCacheLockObject(object modelCacheKey)
|
||||
{
|
||||
if (modelCacheKey == null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException($"modelCacheKey is null cant {nameof(GetCacheLockObject)}");
|
||||
}
|
||||
if (_locks.Count == 1)
|
||||
{
|
||||
return _locks[0];
|
||||
}
|
||||
|
||||
var hashCode = (modelCacheKey.ToString()??"").GetHashCode();
|
||||
var index = Math.Abs(hashCode%_locks.Count);
|
||||
return _locks[index];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace ShardingCore.Core.ModelCacheLockerProviders
|
||||
{
|
||||
public interface IModelCacheLockerProvider
|
||||
{
|
||||
object GetCacheLockObject(object modelCacheKey);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using ShardingCore.Core.DbContextCreator;
|
|||
using ShardingCore.Core.DbContextOptionBuilderCreator;
|
||||
using ShardingCore.Core.DbContextTypeAwares;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ModelCacheLockerProviders;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
|
@ -30,6 +31,7 @@ namespace ShardingCore.Core.RuntimeContexts
|
|||
public interface IShardingRuntimeContext
|
||||
{
|
||||
Type DbContextType { get; }
|
||||
IModelCacheLockerProvider GetModelCacheLockerProvider();
|
||||
IDbContextTypeAware GetDbContextTypeAware();
|
||||
IShardingProvider GetShardingProvider();
|
||||
IDbContextOptionBuilderCreator GetDbContextOptionBuilderCreator();
|
||||
|
|
|
@ -7,6 +7,7 @@ using ShardingCore.Core.DbContextCreator;
|
|||
using ShardingCore.Core.DbContextOptionBuilderCreator;
|
||||
using ShardingCore.Core.DbContextTypeAwares;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ModelCacheLockerProviders;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
|
@ -79,6 +80,13 @@ namespace ShardingCore.Core.RuntimeContexts
|
|||
return _dbContextTypeAware??=GetRequiredService<IDbContextTypeAware>();
|
||||
}
|
||||
|
||||
private IModelCacheLockerProvider _modelCacheLockerProvider;
|
||||
public IModelCacheLockerProvider GetModelCacheLockerProvider()
|
||||
{
|
||||
return _modelCacheLockerProvider??=GetRequiredService<IModelCacheLockerProvider>();
|
||||
}
|
||||
|
||||
|
||||
private IShardingProvider _shardingProvider;
|
||||
|
||||
|
||||
|
@ -317,6 +325,7 @@ namespace ShardingCore.Core.RuntimeContexts
|
|||
GetUnionAllMergeManager();
|
||||
GetShardingPageManager();
|
||||
GetDataSourceInitializer();
|
||||
GetModelCacheLockerProvider();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,10 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
/// </summary>
|
||||
public class ShardingConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 模型缓存锁等级
|
||||
/// </summary>
|
||||
public int CacheModelLockConcurrencyLevel { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// 是否使用代理模式
|
||||
/// </summary>
|
||||
|
|
|
@ -9,6 +9,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
|||
* @Date: Sunday, 22 August 2021 09:44:54
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 多模型比如join
|
||||
/// </summary>
|
||||
public interface IMultiQueryRouteTail: IRouteTail, INoCacheRouteTail
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 不缓存的模型
|
||||
/// </summary>
|
||||
/// Author: xjm
|
||||
/// Created: 2022/4/15 13:22:07
|
||||
|
|
|
@ -10,20 +10,22 @@ using ShardingCore.Sharding.Abstractions;
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
public class ShardingModelSource: ModelSource, IShardingModelSource
|
||||
public class ShardingModelSource: ModelSource
|
||||
{
|
||||
private readonly object _syncObject = new object();
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
private readonly ConcurrentDictionary<object, Lazy<IModel>> _models = new ConcurrentDictionary<object, Lazy<IModel>>();
|
||||
|
||||
/// <summary>
|
||||
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
|
||||
/// directly from your code. This API may change or be removed in future releases.
|
||||
/// </summary>
|
||||
public ShardingModelSource( ModelSourceDependencies dependencies):base(dependencies)
|
||||
public ShardingModelSource( ModelSourceDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext):base(dependencies)
|
||||
{
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
Check.NotNull(dependencies, nameof(dependencies));
|
||||
|
||||
Dependencies = dependencies;
|
||||
|
@ -65,7 +67,8 @@ namespace ShardingCore.EFCores
|
|||
{
|
||||
waitSeconds = shardingModelCacheOption.GetModelCacheLockObjectSeconds();
|
||||
}
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
var cacheLockObject = _shardingRuntimeContext.GetModelCacheLockerProvider().GetCacheLockObject(cacheKey);
|
||||
var acquire = Monitor.TryEnter(cacheLockObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
|
@ -82,38 +85,12 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
Monitor.Exit(cacheLockObject);
|
||||
}
|
||||
}
|
||||
|
||||
return model.Value;
|
||||
}
|
||||
|
||||
public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
{
|
||||
return Dependencies.ModelCacheKeyFactory;
|
||||
}
|
||||
public object GetSyncObject()
|
||||
{
|
||||
return _syncObject;
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
}
|
||||
try
|
||||
{
|
||||
_models.TryRemove(key, out var x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,23 +11,24 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
|||
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
public class ShardingModelSource: ModelSource, IShardingModelSource
|
||||
public class ShardingModelSource: ModelSource
|
||||
{
|
||||
|
||||
private readonly object _syncObject = new object();
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ModelSource" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="dependencies"> The dependencies to use. </param>
|
||||
public ShardingModelSource( ModelSourceDependencies dependencies):base(dependencies)
|
||||
public ShardingModelSource( ModelSourceDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext):base(dependencies)
|
||||
{
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
Check.NotNull(dependencies, nameof(dependencies));
|
||||
|
||||
Dependencies = dependencies;
|
||||
|
@ -79,7 +80,8 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
// Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
var cacheLockObject = _shardingRuntimeContext.GetModelCacheLockerProvider().GetCacheLockObject(cacheKey);
|
||||
var acquire = Monitor.TryEnter(cacheLockObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
|
@ -94,39 +96,12 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
Monitor.Exit(cacheLockObject);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
{
|
||||
return Dependencies.ModelCacheKeyFactory;
|
||||
}
|
||||
|
||||
public object GetSyncObject()
|
||||
{
|
||||
return _syncObject;
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
}
|
||||
try
|
||||
{
|
||||
var cache = Dependencies.MemoryCache;
|
||||
cache.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,22 +12,24 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
|||
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
public class ShardingModelSource : ModelSource, IShardingModelSource
|
||||
public class ShardingModelSource : ModelSource
|
||||
{
|
||||
private readonly object _syncObject = new object();
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ModelSource" /> instance.
|
||||
/// </summary>
|
||||
/// <param name="dependencies"> The dependencies to use. </param>
|
||||
public ShardingModelSource([NotNull] ModelSourceDependencies dependencies) : base(dependencies)
|
||||
public ShardingModelSource([NotNull] ModelSourceDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies)
|
||||
{
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
|
||||
Dependencies = dependencies;
|
||||
}
|
||||
|
@ -93,8 +95,9 @@ namespace ShardingCore.EFCores
|
|||
size = shardingModelCacheOption.GetModelCacheEntrySize();
|
||||
waitSeconds = shardingModelCacheOption.GetModelCacheLockObjectSeconds();
|
||||
}
|
||||
var cacheLockObject = _shardingRuntimeContext.GetModelCacheLockerProvider().GetCacheLockObject(cacheKey);
|
||||
// Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
var acquire = Monitor.TryEnter(cacheLockObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
|
@ -109,40 +112,12 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
Monitor.Exit(cacheLockObject);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
{
|
||||
return Dependencies.ModelCacheKeyFactory;
|
||||
}
|
||||
|
||||
public object GetSyncObject()
|
||||
{
|
||||
return _syncObject;
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
// Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
}
|
||||
try
|
||||
{
|
||||
var cache = Dependencies.MemoryCache;
|
||||
cache.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,16 +15,18 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
|
||||
public class ShardingModelSource : ModelSource, IShardingModelSource
|
||||
public class ShardingModelSource : ModelSource
|
||||
{
|
||||
private readonly object _syncObject = new();
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
|
||||
public ShardingModelSource(ModelSourceDependencies dependencies) : base(dependencies)
|
||||
public ShardingModelSource(ModelSourceDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies)
|
||||
{
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
Check.NotNull(dependencies, nameof(dependencies));
|
||||
Dependencies = dependencies;
|
||||
}
|
||||
|
@ -107,8 +109,10 @@ namespace ShardingCore.EFCores
|
|||
size = shardingModelCacheOption.GetModelCacheEntrySize();
|
||||
waitSeconds = shardingModelCacheOption.GetModelCacheLockObjectSeconds();
|
||||
}
|
||||
|
||||
var cacheLockObject = _shardingRuntimeContext.GetModelCacheLockerProvider().GetCacheLockObject(cacheKey);
|
||||
// Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
var acquire = Monitor.TryEnter(cacheLockObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
|
@ -128,41 +132,41 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
Monitor.Exit(cacheLockObject);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
{
|
||||
return Dependencies.ModelCacheKeyFactory;
|
||||
}
|
||||
// public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
// {
|
||||
// return Dependencies.ModelCacheKeyFactory;
|
||||
// }
|
||||
//
|
||||
// public object GetSyncObject()
|
||||
// {
|
||||
// return _syncObject;
|
||||
// }
|
||||
|
||||
public object GetSyncObject()
|
||||
{
|
||||
return _syncObject;
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
var cache = Dependencies.MemoryCache;
|
||||
cache.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
}
|
||||
}
|
||||
// public void Remove(object key)
|
||||
// {
|
||||
// var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
// if (!acquire)
|
||||
// {
|
||||
// throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
// }
|
||||
// try
|
||||
// {
|
||||
//
|
||||
// var cache = Dependencies.MemoryCache;
|
||||
// cache.Remove(key);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// Monitor.Exit(_syncObject);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -10,16 +10,18 @@ using ShardingCore.Exceptions;
|
|||
using ShardingCore.Sharding.Abstractions;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
|
||||
public class ShardingModelSource : ModelSource, IShardingModelSource
|
||||
public class ShardingModelSource : ModelSource
|
||||
{
|
||||
private readonly object _syncObject = new();
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
|
||||
public ShardingModelSource(ModelSourceDependencies dependencies) : base(dependencies)
|
||||
public ShardingModelSource(ModelSourceDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies)
|
||||
{
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
Check.NotNull(dependencies, nameof(dependencies));
|
||||
Dependencies = dependencies;
|
||||
}
|
||||
|
@ -73,8 +75,9 @@ namespace ShardingCore.EFCores
|
|||
size = shardingModelCacheOption.GetModelCacheEntrySize();
|
||||
waitSeconds = shardingModelCacheOption.GetModelCacheLockObjectSeconds();
|
||||
}
|
||||
var cacheLockObject = _shardingRuntimeContext.GetModelCacheLockerProvider().GetCacheLockObject(cacheKey);
|
||||
// Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
var acquire = Monitor.TryEnter(cacheLockObject, TimeSpan.FromSeconds(waitSeconds));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
|
@ -94,41 +97,12 @@ namespace ShardingCore.EFCores
|
|||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
Monitor.Exit(cacheLockObject);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public IModelCacheKeyFactory GetModelCacheKeyFactory()
|
||||
{
|
||||
return Dependencies.ModelCacheKeyFactory;
|
||||
}
|
||||
|
||||
public object GetSyncObject()
|
||||
{
|
||||
return _syncObject;
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
var acquire = Monitor.TryEnter(_syncObject, TimeSpan.FromSeconds(3));
|
||||
if (!acquire)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
var cache = Dependencies.MemoryCache;
|
||||
cache.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_syncObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,17 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
public interface IShardingModelSource
|
||||
{
|
||||
IModelCacheKeyFactory GetModelCacheKeyFactory();
|
||||
object GetSyncObject();
|
||||
void Remove(object key);
|
||||
|
||||
}
|
||||
}
|
||||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Linq;
|
||||
// using System.Text;
|
||||
// using System.Threading.Tasks;
|
||||
// using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
//
|
||||
// namespace ShardingCore.EFCores
|
||||
// {
|
||||
// public interface IShardingModelSource
|
||||
// {
|
||||
// IModelCacheKeyFactory GetModelCacheKeyFactory();
|
||||
// object GetSyncObject();
|
||||
// void Remove(object key);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -315,52 +315,52 @@ namespace ShardingCore.Extensions
|
|||
/// 移除模型缓存
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
public static void RemoveModelCache(this DbContext dbContext)
|
||||
{
|
||||
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6 && !EFCORE7
|
||||
throw new NotImplementedException();
|
||||
#endif
|
||||
#if EFCORE6 || EFCORE7
|
||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
object key1 = modelCacheKeyFactory.Create(dbContext,true);
|
||||
shardingModelSource.Remove(key1);
|
||||
object key2 = modelCacheKeyFactory.Create(dbContext,false);
|
||||
shardingModelSource.Remove(key2);
|
||||
#endif
|
||||
#if EFCORE5
|
||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
shardingModelSource.Remove(key1);
|
||||
#endif
|
||||
#if EFCORE3
|
||||
|
||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
shardingModelSource.Remove(key1);
|
||||
#endif
|
||||
// public static void RemoveModelCache(this DbContext dbContext)
|
||||
// {
|
||||
// #if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6 && !EFCORE7
|
||||
// throw new NotImplementedException();
|
||||
// #endif
|
||||
// #if EFCORE6 || EFCORE7
|
||||
// var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
// var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
// object key1 = modelCacheKeyFactory.Create(dbContext,true);
|
||||
// shardingModelSource.Remove(key1);
|
||||
// object key2 = modelCacheKeyFactory.Create(dbContext,false);
|
||||
// shardingModelSource.Remove(key2);
|
||||
// #endif
|
||||
// #if EFCORE5
|
||||
// var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
// var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
// object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
// shardingModelSource.Remove(key1);
|
||||
// #endif
|
||||
// #if EFCORE3
|
||||
//
|
||||
// var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
// var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
// object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
// shardingModelSource.Remove(key1);
|
||||
// #endif
|
||||
//
|
||||
// #if EFCORE2
|
||||
//
|
||||
// var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
// var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
// object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
// shardingModelSource.Remove(key1);
|
||||
// #endif
|
||||
// }
|
||||
|
||||
#if EFCORE2
|
||||
|
||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||
object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||
shardingModelSource.Remove(key1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取模型创建的锁
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <returns></returns>
|
||||
public static object GetModelCacheSyncObject(this DbContext dbContext)
|
||||
{
|
||||
IShardingModelSource shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
return shardingModelSource.GetSyncObject();
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 获取模型创建的锁
|
||||
// /// </summary>
|
||||
// /// <param name="dbContext"></param>
|
||||
// /// <returns></returns>
|
||||
// public static object GetModelCacheSyncObject(this DbContext dbContext)
|
||||
// {
|
||||
// IShardingModelSource shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||
// return shardingModelSource.GetSyncObject();
|
||||
// }
|
||||
|
||||
|
||||
public static IEnumerable<object> GetPrimaryKeyValues<TEntity>(TEntity entity,IKey primaryKey) where TEntity : class
|
||||
|
|
|
@ -32,6 +32,7 @@ using ShardingCore.Bootstrappers;
|
|||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.DbContextOptionBuilderCreator;
|
||||
using ShardingCore.Core.DbContextTypeAwares;
|
||||
using ShardingCore.Core.ModelCacheLockerProviders;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.ShardingConfigurations.ConfigBuilders;
|
||||
|
@ -137,6 +138,7 @@ namespace ShardingCore
|
|||
services.TryAddSingleton<IDbContextTypeAware>(sp=>new DbContextTypeAware(typeof(TShardingDbContext)));
|
||||
services.TryAddSingleton<IShardingInitializer, ShardingInitializer>();
|
||||
services.TryAddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
||||
services.TryAddSingleton<IModelCacheLockerProvider, DefaultModelCacheLockerProvider>();
|
||||
services.TryAddSingleton<IDataSourceInitializer, DataSourceInitializer>();
|
||||
services.TryAddSingleton<ITableRouteManager, TableRouteManager>();
|
||||
services
|
||||
|
|
Loading…
Reference in New Issue