此代码线程是否安全?
public static NpgsqlConnection getConnection()
{
NpgsqlConnectionStringBuilder csb = new NpgsqlConnectionStringBuilder();
csb.Host = ConfigurationManager.AppSettings["server"];
csb.Password = ConfigurationManager.AppSettings["password"];
csb.Pooling = true;
csb.UserName = ConfigurationManager.AppSettings["username"];
csb.Port = Convert.ToInt32( ConfigurationManager.AppSettings["port"]);
csb.Enlist = true;
//csb.Database = ConfigurationManager.AppSettings["databaseName"];
return new NpgsqlConnection(csb.ConnectionString);
}
我在处使用此连接,但有时我会得到TimeoutException
。
发生了超时。如果要建立连接,请在ConnectionString中增加Timeout值。如果您正在执行命令,请在ConnectionString或NpgsqlCommand对象中增加CommandTimeout值。
有什么想法吗?
答案 0 :(得分:4)
回答你的问题,NpgsqlConnection不是线程安全的。您不应该与多个线程共享NpgsqlConnection。
但是关于你的异常,如果你注意到,你在调用NpgsqlConnection.Open()方法时会得到它。在getConnection()方法中,不要调用Open。您正在其他地方打开连接。
现在,要在打开连接时获得此异常,您必须已达到最大连接池大小。这意味着您可能没有关闭先前打开的连接。
您必须在NpgsqlConnection对象中调用close或dispose才能将其返回到连接池。如果您让NpgsqlConnection实例超出范围,它将不会返回到池并将计为已使用的连接。
为了检查这是否是您的问题,您有两种可能:
禁用连接池。您将不再获得此异常,但由于您没有正确关闭连接,您最终可能会达到每个数据库允许的最大连接数。这是postgresql服务器参数。
调用NpgsqlConnection.ClearPool或ClearAllPool以删除池中的所有连接。
请注意,这两种可能性仅用于检查您是否遇到连接池问题。如果您的应用程序在使用其中一种方法后开始正常工作,那么您的应用程序仍然存在需要修复的问题。
我希望它有所帮助。
答案 1 :(得分:1)
不,这不是线程安全的,因为csb不是本地的,可能不是线程安全的。使用本地csb。检查ConfigurationManager是否是线程安全的。
实例化连接本身是线程安全的,因为其他线程无法“看到”实例。您的连接问题可能源于其他地方。您可能希望尝试在错误消息中提供的提示。