【问题标题】:NpgsqlConnection.Open opens remote connection even when there is no internet即使没有互联网,NpgsqlConnection.Open 也会打开远程连接
【发布时间】:2017-12-01 03:43:00
【问题描述】:

这是我在这里的第一个问题。

所以我有这个应用程序,它使用 Npgsql 库连接到远程数据库。 我有一个连接到数据库的方法,执行查询,最后关闭连接。 可以正常使用,但是问题是如果程序在运行但没有调用该方法的时候,我断开WiFi模拟无法连接服务器,然后运行该方法,连接方法仍然可以打开连接。这会导致查询卡住。 我似乎无法找到一种方法来检查我是否可以连接到服务器,因为即使我断开了互联网,NpgsqlConnection.Open() 方法仍然会打开它。

对不起我的英语

 public static NpgsqlConnection ConnectRemote()
    {
        try
        {
            remoteConnection = new NpgsqlConnection("Server = " + remoteData.server + "; " +
                                              "Port = " + remoteData.port + "; " +
                                              "User Id = " + remoteData.user + "; " +
                                              "Password = " + remoteData.password + "; " +
                                              "Database = " + remoteData.dataBase + "; ");

            remoteConnection.Open();
        }
        catch (NpgsqlException ex)
        {
            throw;
        }
        catch (Exception ex)
        {
            remoteConnection.Close();
            remoteConnection = null;
        }
        return remoteConnection;

    }

public static bool CheckRemote()
    {
            if (remoteConnection != null)
            {
                if (remoteConnection.FullState.Equals(ConnectionState.Open))
                    return true;
                return false;
            }
            return false;
    }

public bool AddNewProduct(Product product)
    {
        try
        {
            DBManager.ConnectLocal();
            DBManager.ConnectRemote();
            object[] parameters;

            if (DBManager.CheckRemote())
            {
                if (!DBManager.isSyncronized)
                {
                    DBManager.Syncronize();
                }

                parameters = new object[8];
                parameters[0] = 1;
                parameters[1] = product.id;
                parameters[2] = product.description;
                parameters[3] = (decimal)product.salePrice;
                parameters[4] = (decimal)product.cost;
                parameters[5] = product.minStock;
                parameters[6] = product.providerName;
                parameters[7] = product.category;
                DBManager.RunFunction(DBManager.remoteConnection, DBProcedures.createProduct, parameters);
            }
            else
            {
                string sql = "select * from createproduct(1, " + product.id + ", '" + product.description + "', " + (decimal)product.salePrice + ", " 
                    + (decimal)product.cost + ", " + product.minStock + ", '" + product.providerName + "', '" + product.category + "'); ";
                parameters = new object[1];
                parameters[0] = sql;
                DBManager.RunFunction(DBManager.localConnection, "addsync", parameters);

                DBManager.isSyncronized = false;

            }

            parameters = new object[6];
            parameters[0] = product.description;
            parameters[1] = (decimal)product.salePrice;
            parameters[2] = (decimal)product.cost;
            parameters[3] = product.minStock;
            parameters[4] = product.providerName;
            parameters[5] = product.category;

            DataTable result = DBManager.RunFunction(DBManager.localConnection, DBProcedures.createProduct, parameters);
            DBManager.DisconnectLocal();
            DBManager.DisconnectRemote();
            return true;
        }
        catch (Npgsql.NpgsqlException ex)
        {
            return false;
        }           
    }

【问题讨论】:

  • 您的问题并不完全清楚,但您可能只是看到连接池在工作。默认情况下,当你关闭一个连接时,Npgsql 实际上保持它在内部打开。当您下次打开一个连接时,它将重用以前的连接而不是打开一个新的连接——这对性能非常重要。所以你在池中有一个连接,Open() 并没有真正做任何事情,但是如果你的网络出现故障,你的查询就会失败。

标签: c# postgresql state npgsql


【解决方案1】:

一些事情——一件不相关,两件相关。我希望这些的一些组合会有所帮助。

  1. 首先,不相关的评论。 NpgSqlStringBuilder 类是帮助揭开连接字符串神秘面纱的好工具。我意识到你的工作,但由于你必须进行编辑(我会在一分钟内建议),我发现它比导航String.Format 更容易使用,就像查询参数更容易(除了更安全)比尝试通过将参数传递给查询来string.Format。此外,在您的连接字符串中声明 ApplicationName 以帮助诊断服务器上究竟发生了什么,就像您将在下一条评论中看到的那样。

  2. 如果您使用连接池,当连接关闭时,我认为它并没有真正关闭——甚至在数据库上也没有。如果你打开服务器管理员,你会明白我的意思——它有点悬在那里,等待被重用。尝试在连接字符串中设置pooled=false,以确保在关闭连接时真正关闭它。

  3. 如果这不起作用,请尝试一个简单的查询。在您不需要它的情况下,成本将是最低的,并且无疑会在您确实需要它时修复您的用例。

所有三个建议都在这里体现:

public static NpgsqlConnection ConnectRemote()
{
    NpgsqlConnectionStringBuilder sb = new NpgsqlConnectionStringBuilder();
    sb.ApplicationName = "Connection Tester";
    sb.Host = remoteData.server;
    sb.Port = remoteData.port;
    sb.Username = remoteData.user;
    sb.Password = remoteData.password;
    sb.Database = remoteData.database;
    sb.Pooling = false;

    remoteConnection = new NpgsqlConnection(sb.ToString());

    try
    {
        remoteConnection.Open();
        NpgSqlCommand test = new NpgSqlCommand("select 1", remoteConnection);
        test.ExecuteScalar();
    }
    catch (NpgsqlException ex)
    {
       throw;
    }
    catch (Exception ex)
    {
       remoteConnection.Close();
       remoteConnection = null;
    }
    return remoteConnection;
}

【讨论】:

    猜你喜欢
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多