这个NpgsqlConnection工厂线程安全吗?

时间:2013-12-04 10:48:04

标签: .net thread-safety npgsql

此代码线程是否安全?

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值。

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

回答你的问题,NpgsqlConnection不是线程安全的。您不应该与多个线程共享NpgsqlConnection。

但是关于你的异常,如果你注意到,你在调用NpgsqlConnection.Open()方法时会得到它。在getConnection()方法中,不要调用Open。您正在其他地方打开连接。

现在,要在打开连接时获得此异常,您必须已达到最大连接池大小。这意味着您可能没有关闭先前打开的连接。

您必须在NpgsqlConnection对象中调用close或dispose才能将其返回到连接池。如果您让NpgsqlConnection实例超出范围,它将不会返回到池并将计为已使用的连接。

为了检查这是否是您的问题,您有两种可能:

  1. 禁用连接池。您将不再获得此异常,但由于您没有正确关闭连接,您最终可能会达到每个数据库允许的最大连接数。这是postgresql服务器参数。

  2. 调用NpgsqlConnection.ClearPool或ClearAllPool以删除池中的所有连接。

  3. 请注意,这两种可能性仅用于检查您是否遇到连接池问题。如果您的应用程序在使用其中一种方法后开始正常工作,那么您的应用程序仍然存在需要修复的问题。

    我希望它有所帮助。

答案 1 :(得分:1)

不,这不是线程安全的,因为csb不是本地的,可能不是线程安全的。使用本地csb。检查ConfigurationManager是否是线程安全的。

实例化连接本身是线程安全的,因为其他线程无法“看到”实例。您的连接问题可能源于其他地方。您可能希望尝试在错误消息中提供的提示。