mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	防止同连接字符串被IFreeSql使用多次,发生连接池溢出bug(ado.net连接池原理,减少解释成本)
This commit is contained in:
		@@ -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();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user