C# MySQL 连接器:连接池不工作
C# MySQL Connector: Connection pools are not working
我想利用连接池,这样我就可以在不将 MysqlConnection 对象传递给每个 class 的情况下使用数据库。我有这样的代码:
Main.cs:
namespace batman
{
class Program
{
static void Main(string[] args)
{
using (MysqlConnection conn = new MysqlConnection("Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True"))
{
MonitorClass monitor = new MonitorClass();
monitor.Run();
}
//...
}
}
}
MonitorClass.cs:
namespace batman
{
public class MonitorClass
{
public void Run()
{
using (MySqlConnection conn = new MySqlConnection())
using (MySqlCommand cmd = conn.CreateCommand())
{
try
{
conn.Open();
cmd.CommandText = "SELECT id, package_type FROM package_registry WHERE finish_time <= @ftime";
cmd.Parameters.AddWithValue("@ftime", 0);
cmd.Prepare();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int packageId = reader.GetInt32(0);
string packageType = reader.GetString(1);
Unirest.post("http://localhost/gears/ops/packagefinish")
.field("package", packageId)
.asStringAsync();
Console.WriteLine("[PackageMonitor] Package {0} ({1}) expired", packageId, packageType);
}
}
catch (MySqlException ex)
{
}
}
}
}
}
MonitorClass 应该从连接池中获取连接。
但是一旦我 运行 我的程序它抛出 System.InvalidOperationException 和
Additional information: Unable to connect to any of the specified MySQL hosts.
在:
cmd.Prepare();
现在,我想我做错了什么,但我不知道到底是什么。
Oracle 文档是这样说的
The Connector/Net supports connection pooling for better performance and scalability with database-intensive applications. This is enabled by default. You can turn it off or adjust its performance characteristics using the connection string options Pooling, Connection Reset, Connection Lifetime, Cache Server Properties, Max Pool Size and Min Pool Size. See Section 5.2, “Creating a Connector/Net Connection String” for further information.
Connection pooling works by keeping the native connection to the server live when the client disposes of a MySqlConnection. Subsequently, if a new MySqlConnection object is opened, it will be created from the connection pool, rather than creating a new native connection. This improves performance.
嗯,好像有两个不同的问题:
连接打开了两次 - 第一次在 Main 方法中,第二次(独立地)在 Monitor class 中。这可以通过仅在监视器 class 中打开连接并在其中传递连接字符串来解决。
您从未通过调用 .Open()
方法打开连接。
让我们重构您的代码,牢记这一点:
主要内容:
static void Main(string[] args)
{
var connStr = "Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True";
MonitorClass monitor = new MonitorClass(connStr);
monitor.Run();
//...
}
监控:
public class MonitorClass
{
private readonly string _connStr;
public MonitorClass(string connectionString)
{
this._connStr = connectionString;
}
public void Run()
{
using (MySqlConnection conn = new MySqlConnection(_connStr))
using (MySqlCommand cmd = conn.CreateCommand())
{
conn.Open();
...
}
}
}
我想利用连接池,这样我就可以在不将 MysqlConnection 对象传递给每个 class 的情况下使用数据库。我有这样的代码:
Main.cs:
namespace batman
{
class Program
{
static void Main(string[] args)
{
using (MysqlConnection conn = new MysqlConnection("Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True"))
{
MonitorClass monitor = new MonitorClass();
monitor.Run();
}
//...
}
}
}
MonitorClass.cs:
namespace batman
{
public class MonitorClass
{
public void Run()
{
using (MySqlConnection conn = new MySqlConnection())
using (MySqlCommand cmd = conn.CreateCommand())
{
try
{
conn.Open();
cmd.CommandText = "SELECT id, package_type FROM package_registry WHERE finish_time <= @ftime";
cmd.Parameters.AddWithValue("@ftime", 0);
cmd.Prepare();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int packageId = reader.GetInt32(0);
string packageType = reader.GetString(1);
Unirest.post("http://localhost/gears/ops/packagefinish")
.field("package", packageId)
.asStringAsync();
Console.WriteLine("[PackageMonitor] Package {0} ({1}) expired", packageId, packageType);
}
}
catch (MySqlException ex)
{
}
}
}
}
}
MonitorClass 应该从连接池中获取连接。 但是一旦我 运行 我的程序它抛出 System.InvalidOperationException 和
Additional information: Unable to connect to any of the specified MySQL hosts.
在:
cmd.Prepare();
现在,我想我做错了什么,但我不知道到底是什么。
Oracle 文档是这样说的
The Connector/Net supports connection pooling for better performance and scalability with database-intensive applications. This is enabled by default. You can turn it off or adjust its performance characteristics using the connection string options Pooling, Connection Reset, Connection Lifetime, Cache Server Properties, Max Pool Size and Min Pool Size. See Section 5.2, “Creating a Connector/Net Connection String” for further information.
Connection pooling works by keeping the native connection to the server live when the client disposes of a MySqlConnection. Subsequently, if a new MySqlConnection object is opened, it will be created from the connection pool, rather than creating a new native connection. This improves performance.
嗯,好像有两个不同的问题:
连接打开了两次 - 第一次在 Main 方法中,第二次(独立地)在 Monitor class 中。这可以通过仅在监视器 class 中打开连接并在其中传递连接字符串来解决。
您从未通过调用
.Open()
方法打开连接。
让我们重构您的代码,牢记这一点:
主要内容:
static void Main(string[] args)
{
var connStr = "Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True";
MonitorClass monitor = new MonitorClass(connStr);
monitor.Run();
//...
}
监控:
public class MonitorClass
{
private readonly string _connStr;
public MonitorClass(string connectionString)
{
this._connStr = connectionString;
}
public void Run()
{
using (MySqlConnection conn = new MySqlConnection(_connStr))
using (MySqlCommand cmd = conn.CreateCommand())
{
conn.Open();
...
}
}
}