C#Mysql - 在async await服务器上使用数据库查询锁

Eri*_*tný 10 c# mysql connection ado.net async-await

我TcpListener上课,我正在async/await阅读和写作.

对于这个服务器,我创建了单个数据库实例,我准备了所有数据库查询.

但是对于一个以上,TcpClient我一直在例外:

MySql.Data.MySqlClient.MySqlException发生了类型的异常,MySql.Data.dll但未在用户代码中处理

附加信息:已经有一个DataReader与此相关的开放Connection,必须先关闭.

如果我理解正确的话,那么一次数据库查询就不会超过一个async客户端.

所以我只是在我的查询中添加了锁,这样一切似乎都很好.

   // One MySqlConnection instance for whole program.

   lock (thisLock)
   {
    var cmd = connection.CreateCommand();

    cmd.CommandText = "SELECT Count(*) FROM logins WHERE username = @user AND password = @pass";
    cmd.Parameters.AddWithValue("@user", username);
    cmd.Parameters.AddWithValue("@pass", password);

    var count = int.Parse(cmd.ExecuteScalar().ToString());
    return count > 0;
}
Run Code Online (Sandbox Code Playgroud)

我也尝试使用这个方法为每个查询创建新连接,如SO社区的某个人所提到的,但这个方法比锁慢得多:

    using (MySqlConnection connection = new MySqlConnection(connectionString))
    {
        connection.Open();   // This takes +- 35ms and makes worse performance than locks

        using (MySqlCommand cmd = connection.CreateCommand())
        {
            cmd.CommandText = "SELECT Count(*) FROM logins WHERE username = @user AND password = @pass";
            cmd.Parameters.AddWithValue("@user", username);
            cmd.Parameters.AddWithValue("@pass", password);

            int count = int.Parse(cmd.ExecuteScalar().ToString());
            return count > 0;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我使用秒表对这种方法进行基准测试,并且使用一个锁定连接的查询在+ - 20ms内执行,这只是+ - 网络的延迟,但使用它是+ - 55ms,因为.Open()方法需要+ - 35ms.

如果有更糟糕的表现,为什么很多人会使用方法?或者我做错了什么?

Cod*_*ler 8

你是对的,打开连接是一项耗时的操作.为了缓解这种情况,ADO.NET具有连接池.查看此文章了解详细信息.

如果继续进行性能测试并检查后续连接的时间,您应该看到时间connection.Open()有待改进并接近0毫秒,因为实际上是从池中获取连接.

使用锁实现,实际上只使用一个连接就可以使用连接池.虽然这种方法可以在一个简单的测试中表现出更好的性能,但它在高负载应用程序中会显示非常差的结果.