fix: 区分 SqlSugarScope 和 SqlSugarClient 使用场景
区分: - GetSqlSugarScope(): 返回 SqlSugarScope,用于 DI 注入(Singleton) - GetSqlSugarClient(): 返回 SqlSugarClient,用于后台任务(每次创建新实例) 原因: - SqlSugarScope 使用 AsyncLocal 隔离上下文 - Task.Run 后台线程中 AsyncLocal 可能无法正确传递 - 后台任务使用 SqlSugarClient 更安全,每个实例独立连接 使用: - DI 注入:GetSqlSugarScope() - Repository 后台写入:GetSqlSugarClient() - MySQL 连接池复用底层 TCP 连接,性能开销小
This commit is contained in:
parent
cbe0ac9f4a
commit
dc50dfc917
@ -12,7 +12,7 @@ public static class DatabaseExtensions
|
|||||||
// 使用 Singleton 注册,整个应用共享一个实例
|
// 使用 Singleton 注册,整个应用共享一个实例
|
||||||
services.AddSingleton<ISqlSugarClient>(s =>
|
services.AddSingleton<ISqlSugarClient>(s =>
|
||||||
{
|
{
|
||||||
return SqlSugarConfig.GetSqlSugarClient();
|
return SqlSugarConfig.GetSqlSugarScope();
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddScoped<DatabaseService>();
|
services.AddScoped<DatabaseService>();
|
||||||
|
|||||||
@ -15,6 +15,9 @@ public static class SqlSugarConfig
|
|||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 SqlSugarClient 实例(用于后台任务,每次创建新实例)
|
||||||
|
/// </summary>
|
||||||
public static ISqlSugarClient GetSqlSugarClient()
|
public static ISqlSugarClient GetSqlSugarClient()
|
||||||
{
|
{
|
||||||
if (_configuration == null)
|
if (_configuration == null)
|
||||||
@ -22,36 +25,41 @@ public static class SqlSugarConfig
|
|||||||
throw new InvalidOperationException("SqlSugarConfig has not been initialized. Call Initialize() first.");
|
throw new InvalidOperationException("SqlSugarConfig has not been initialized. Call Initialize() first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先从环境变量读取连接字符串
|
var connectionString = GetConnectionString();
|
||||||
var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings__Default")
|
|
||||||
?? _configuration.GetConnectionString("Default")
|
|
||||||
?? throw new InvalidOperationException("Connection string 'Default' not found in environment variables or configuration.");
|
|
||||||
|
|
||||||
// MySQL 连接池优化配置
|
// 使用 SqlSugarClient(非 Scope),每次创建独立实例
|
||||||
// 添加连接池参数提高稳定性
|
// 适合后台任务、Task.Run 场景
|
||||||
if (!connectionString.Contains("Pooling=", StringComparison.OrdinalIgnoreCase))
|
return new SqlSugarClient(new ConnectionConfig()
|
||||||
{
|
{
|
||||||
connectionString += ";Pooling=true";
|
ConnectionString = connectionString,
|
||||||
}
|
DbType = DbType.MySql,
|
||||||
if (!connectionString.Contains("MaximumPoolSize=", StringComparison.OrdinalIgnoreCase))
|
IsAutoCloseConnection = true,
|
||||||
|
InitKeyType = InitKeyType.Attribute,
|
||||||
|
ConfigureExternalServices = new ConfigureExternalServices
|
||||||
{
|
{
|
||||||
connectionString += ";MaximumPoolSize=100";
|
EntityService = (property, column) =>
|
||||||
}
|
|
||||||
if (!connectionString.Contains("MinimumPoolSize=", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
connectionString += ";MinimumPoolSize=5";
|
if (property.PropertyType == typeof(DateTime))
|
||||||
}
|
|
||||||
// 连接超时和生命周期
|
|
||||||
if (!connectionString.Contains("ConnectionTimeout=", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
connectionString += ";ConnectionTimeout=30";
|
column.DataType = "datetime(3)";
|
||||||
}
|
}
|
||||||
// 连接空闲超时,避免使用长时间空闲的连接
|
}
|
||||||
if (!connectionString.Contains("ConnectionIdleTimeout=", StringComparison.OrdinalIgnoreCase))
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取 SqlSugarScope 实例(用于 DI 注入,Singleton/Scoped)
|
||||||
|
/// </summary>
|
||||||
|
public static ISqlSugarClient GetSqlSugarScope()
|
||||||
{
|
{
|
||||||
connectionString += ";ConnectionIdleTimeout=180";
|
if (_configuration == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("SqlSugarConfig has not been initialized. Call Initialize() first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var connectionString = GetConnectionString();
|
||||||
|
|
||||||
return new SqlSugarScope(new ConnectionConfig()
|
return new SqlSugarScope(new ConnectionConfig()
|
||||||
{
|
{
|
||||||
ConnectionString = connectionString,
|
ConnectionString = connectionString,
|
||||||
@ -70,4 +78,35 @@ public static class SqlSugarConfig
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetConnectionString()
|
||||||
|
{
|
||||||
|
var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings__Default")
|
||||||
|
?? _configuration!.GetConnectionString("Default")
|
||||||
|
?? throw new InvalidOperationException("Connection string 'Default' not found in environment variables or configuration.");
|
||||||
|
|
||||||
|
// MySQL 连接池优化配置
|
||||||
|
if (!connectionString.Contains("Pooling=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
connectionString += ";Pooling=true";
|
||||||
|
}
|
||||||
|
if (!connectionString.Contains("MaximumPoolSize=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
connectionString += ";MaximumPoolSize=100";
|
||||||
|
}
|
||||||
|
if (!connectionString.Contains("MinimumPoolSize=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
connectionString += ";MinimumPoolSize=5";
|
||||||
|
}
|
||||||
|
if (!connectionString.Contains("ConnectionTimeout=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
connectionString += ";ConnectionTimeout=30";
|
||||||
|
}
|
||||||
|
if (!connectionString.Contains("ConnectionIdleTimeout=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
connectionString += ";ConnectionIdleTimeout=180";
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectionString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user