优化动态分库的demo

This commit is contained in:
xuejiaming 2022-11-24 14:01:39 +08:00
parent cce5875191
commit bee07e9ec2
2 changed files with 42 additions and 16 deletions

View File

@ -18,20 +18,22 @@ namespace Sample.AutoCreateIfPresent
private const string TABLE_NAME = "TABLE_NAME"; private const string TABLE_NAME = "TABLE_NAME";
private const string CurrentTableName = nameof(AreaDevice); private const string CurrentTableName = nameof(AreaDevice);
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
private readonly object _lock = new object();
public AreaDeviceRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator tableCreator) private readonly ConcurrentDictionary<string, object?> _tails =
new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
private readonly object _lock = new object();
private readonly object _initLock = new object();
private bool _inited = false;
public AreaDeviceRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator tableCreator)
{ {
_virtualDataSource = virtualDataSource; _virtualDataSource = virtualDataSource;
_tableCreator = tableCreator; _tableCreator = tableCreator;
InitTails();
} }
private void InitTails() private void InitTails()
{ {
using (var connection = new MySqlConnection(_virtualDataSource.DefaultConnectionString)) using (var connection = new MySqlConnection(_virtualDataSource.DefaultConnectionString))
{ {
connection.Open(); connection.Open();
@ -45,22 +47,23 @@ namespace Sample.AutoCreateIfPresent
if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase)) if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
{ {
var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty; var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty;
if (tableName.StartsWith(CurrentTableName,StringComparison.OrdinalIgnoreCase)) if (tableName.StartsWith(CurrentTableName, StringComparison.OrdinalIgnoreCase))
{ {
//如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1 //如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
_tails.TryAdd(tableName.Substring(CurrentTableName.Length+1), null); _tails.TryAdd(tableName.Substring(CurrentTableName.Length + 1), null);
} }
} }
} }
} }
} }
} }
public override string ShardingKeyToTail(object shardingKey) public override string ShardingKeyToTail(object shardingKey)
{ {
return $"{shardingKey}"; return $"{shardingKey}";
} }
/// <summary> /// <summary>
/// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀 /// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
/// 仅启动时调用 /// 仅启动时调用
@ -68,6 +71,18 @@ namespace Sample.AutoCreateIfPresent
/// <returns></returns> /// <returns></returns>
public override List<string> GetTails() public override List<string> GetTails()
{ {
if (!_inited)
{
lock(_initLock)
{
if (!_inited)
{
InitTails();
_inited = true;
}
}
}
return _tails.Keys.ToList(); return _tails.Keys.ToList();
} }
@ -83,17 +98,17 @@ namespace Sample.AutoCreateIfPresent
{ {
case ShardingOperatorEnum.Equal: return tail => tail == t; case ShardingOperatorEnum.Equal: return tail => tail == t;
default: default:
{ {
#if DEBUG #if DEBUG
Console.WriteLine($"shardingOperator is not equal scan all table tail"); Console.WriteLine($"shardingOperator is not equal scan all table tail");
#endif #endif
return tail => true; return tail => true;
} }
} }
} }
public override TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey) public override TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey)
{ {
var shardingKeyToTail = ShardingKeyToTail(shardingKey); var shardingKeyToTail = ShardingKeyToTail(shardingKey);
if (!_tails.TryGetValue(shardingKeyToTail, out var _)) if (!_tails.TryGetValue(shardingKeyToTail, out var _))
{ {
@ -101,7 +116,6 @@ namespace Sample.AutoCreateIfPresent
{ {
if (!_tails.TryGetValue(shardingKeyToTail, out var _)) if (!_tails.TryGetValue(shardingKeyToTail, out var _))
{ {
try try
{ {
_tableCreator.CreateTable<AreaDevice>(_virtualDataSource.DefaultDataSourceName, _tableCreator.CreateTable<AreaDevice>(_virtualDataSource.DefaultDataSourceName,

View File

@ -27,12 +27,13 @@ namespace Sample.AutoCreateIfPresent
private readonly IShardingTableCreator _shardingTableCreator; private readonly IShardingTableCreator _shardingTableCreator;
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
private readonly object _lock = new object(); private readonly object _lock = new object();
private readonly object _initLock = new object();
private bool _inited = false;
public OrderByHourRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator shardingTableCreator) public OrderByHourRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator shardingTableCreator)
{ {
_virtualDataSource = virtualDataSource; _virtualDataSource = virtualDataSource;
_shardingTableCreator = shardingTableCreator; _shardingTableCreator = shardingTableCreator;
InitTails();
} }
private void InitTails() private void InitTails()
@ -82,6 +83,17 @@ namespace Sample.AutoCreateIfPresent
/// <returns></returns> /// <returns></returns>
public override List<string> GetTails() public override List<string> GetTails()
{ {
if (!_inited)
{
lock(_initLock)
{
if (!_inited)
{
InitTails();
_inited = true;
}
}
}
return _tails.Keys.ToList(); return _tails.Keys.ToList();
} }