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

我有TcpListener类,我正在使用async/await读写。

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

但对于一个以上的TcpClient我一直在exception:

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

附加信息:已经有一个与此Connection关联的打开DataReader ,必须先关闭它。

如果我理解正确,那么一次数据库查询就不会超过一个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; } 

我也尝试使用这个方法为每个查询创建新连接,如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; } } 

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

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

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

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

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