mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
防止同连接字符串被IFreeSql使用多次,发生连接池溢出bug(ado.net连接池原理,减少解释成本)
This commit is contained in:
parent
488a6edd4d
commit
84449e57f3
@ -1,6 +1,7 @@
|
|||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using SafeObjectPool;
|
using SafeObjectPool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@ -43,6 +44,7 @@ namespace FreeSql.MySql {
|
|||||||
public bool IsThrowGetTimeoutException { get; set; } = true;
|
public bool IsThrowGetTimeoutException { get; set; } = true;
|
||||||
public int CheckAvailableInterval { get; set; } = 5;
|
public int CheckAvailableInterval { get; set; } = 5;
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
private string _connectionString;
|
private string _connectionString;
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get => _connectionString;
|
get => _connectionString;
|
||||||
@ -51,7 +53,8 @@ namespace FreeSql.MySql {
|
|||||||
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
||||||
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
||||||
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
||||||
PoolSize = poolsize + 1;
|
var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
|
||||||
|
PoolSize = poolsize + connStrIncr;
|
||||||
_connectionString = m.Success ?
|
_connectionString = m.Success ?
|
||||||
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
||||||
$"{connStr};Max pool size={PoolSize}";
|
$"{connStr};Max pool size={PoolSize}";
|
||||||
@ -62,7 +65,6 @@ namespace FreeSql.MySql {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
||||||
if ((obj.Value as MySqlConnection).Ping() == false) obj.Value.Open();
|
if ((obj.Value as MySqlConnection).Ping() == false) obj.Value.Open();
|
||||||
return (obj.Value as MySqlConnection).Ping();
|
return (obj.Value as MySqlConnection).Ping();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Oracle.ManagedDataAccess.Client;
|
using Oracle.ManagedDataAccess.Client;
|
||||||
using SafeObjectPool;
|
using SafeObjectPool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
@ -58,6 +59,7 @@ namespace FreeSql.Oracle {
|
|||||||
public bool IsThrowGetTimeoutException { get; set; } = true;
|
public bool IsThrowGetTimeoutException { get; set; } = true;
|
||||||
public int CheckAvailableInterval { get; set; } = 5;
|
public int CheckAvailableInterval { get; set; } = 5;
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
private string _connectionString;
|
private string _connectionString;
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get => _connectionString;
|
get => _connectionString;
|
||||||
@ -66,7 +68,8 @@ namespace FreeSql.Oracle {
|
|||||||
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
||||||
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
||||||
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
||||||
PoolSize = poolsize + 1;
|
var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
|
||||||
|
PoolSize = poolsize + connStrIncr;
|
||||||
_connectionString = m.Success ?
|
_connectionString = m.Success ?
|
||||||
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
||||||
$"{connStr};Max pool size={PoolSize}";
|
$"{connStr};Max pool size={PoolSize}";
|
||||||
@ -77,7 +80,6 @@ namespace FreeSql.Oracle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
||||||
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
||||||
var cmd = obj.Value.CreateCommand();
|
var cmd = obj.Value.CreateCommand();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Npgsql;
|
using Npgsql;
|
||||||
using SafeObjectPool;
|
using SafeObjectPool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
@ -53,6 +54,7 @@ namespace FreeSql.PostgreSQL {
|
|||||||
public bool IsThrowGetTimeoutException { get; set; } = true;
|
public bool IsThrowGetTimeoutException { get; set; } = true;
|
||||||
public int CheckAvailableInterval { get; set; } = 5;
|
public int CheckAvailableInterval { get; set; } = 5;
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
private string _connectionString;
|
private string _connectionString;
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get => _connectionString;
|
get => _connectionString;
|
||||||
@ -61,7 +63,8 @@ namespace FreeSql.PostgreSQL {
|
|||||||
var poolsizePatern = @"Maximum\s*pool\s*size\s*=\s*(\d+)";
|
var poolsizePatern = @"Maximum\s*pool\s*size\s*=\s*(\d+)";
|
||||||
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
||||||
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
||||||
PoolSize = poolsize + 1;
|
var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
|
||||||
|
PoolSize = poolsize + connStrIncr;
|
||||||
_connectionString = m.Success ?
|
_connectionString = m.Success ?
|
||||||
Regex.Replace(connStr, poolsizePatern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
Regex.Replace(connStr, poolsizePatern, $"Maximum pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
||||||
$"{connStr};Maximum pool size={PoolSize}";
|
$"{connStr};Maximum pool size={PoolSize}";
|
||||||
@ -72,7 +75,6 @@ namespace FreeSql.PostgreSQL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
||||||
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
||||||
var cmd = obj.Value.CreateCommand();
|
var cmd = obj.Value.CreateCommand();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using SafeObjectPool;
|
using SafeObjectPool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
@ -47,6 +48,7 @@ namespace FreeSql.SqlServer {
|
|||||||
public bool IsThrowGetTimeoutException { get; set; } = true;
|
public bool IsThrowGetTimeoutException { get; set; } = true;
|
||||||
public int CheckAvailableInterval { get; set; } = 5;
|
public int CheckAvailableInterval { get; set; } = 5;
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
private string _connectionString;
|
private string _connectionString;
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get => _connectionString;
|
get => _connectionString;
|
||||||
@ -55,7 +57,8 @@ namespace FreeSql.SqlServer {
|
|||||||
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
||||||
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
||||||
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
||||||
PoolSize = poolsize + 1;
|
var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
|
||||||
|
PoolSize = poolsize + connStrIncr;
|
||||||
_connectionString = m.Success ?
|
_connectionString = m.Success ?
|
||||||
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
||||||
$"{connStr};Max pool size={PoolSize}";
|
$"{connStr};Max pool size={PoolSize}";
|
||||||
@ -66,7 +69,6 @@ namespace FreeSql.SqlServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
||||||
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
if (obj.Value.State == ConnectionState.Closed) obj.Value.Open();
|
||||||
var cmd = obj.Value.CreateCommand();
|
var cmd = obj.Value.CreateCommand();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using SafeObjectPool;
|
using SafeObjectPool;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
@ -49,6 +50,7 @@ namespace FreeSql.Sqlite {
|
|||||||
public int CheckAvailableInterval { get; set; } = 5;
|
public int CheckAvailableInterval { get; set; } = 5;
|
||||||
public string[] Attaches = new string[0];
|
public string[] Attaches = new string[0];
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, int> dicConnStrIncr = new ConcurrentDictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
private string _connectionString;
|
private string _connectionString;
|
||||||
public string ConnectionString {
|
public string ConnectionString {
|
||||||
get => _connectionString;
|
get => _connectionString;
|
||||||
@ -57,7 +59,8 @@ namespace FreeSql.Sqlite {
|
|||||||
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
var poolsizePatern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
||||||
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
Match m = Regex.Match(connStr, poolsizePatern, RegexOptions.IgnoreCase);
|
||||||
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
if (m.Success == false || int.TryParse(m.Groups[1].Value, out var poolsize) == false || poolsize <= 0) poolsize = 100;
|
||||||
PoolSize = poolsize + 1;
|
var connStrIncr = dicConnStrIncr.AddOrUpdate(connStr, 1, (oldkey, oldval) => oldval + 1);
|
||||||
|
PoolSize = poolsize + connStrIncr;
|
||||||
_connectionString = m.Success ?
|
_connectionString = m.Success ?
|
||||||
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
Regex.Replace(connStr, poolsizePatern, $"Max pool size={PoolSize}", RegexOptions.IgnoreCase) :
|
||||||
$"{connStr};Max pool size={PoolSize}";
|
$"{connStr};Max pool size={PoolSize}";
|
||||||
@ -74,7 +77,6 @@ namespace FreeSql.Sqlite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
public bool OnCheckAvailable(Object<DbConnection> obj) {
|
||||||
if ((obj.Value as SQLiteConnection).Ping() == false) obj.Value.OpenAndAttach(Attaches);
|
if ((obj.Value as SQLiteConnection).Ping() == false) obj.Value.OpenAndAttach(Attaches);
|
||||||
return (obj.Value as SQLiteConnection).Ping();
|
return (obj.Value as SQLiteConnection).Ping();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user