应用程序上的并发用户导致MySQL数据库错误
问题描述:
我有一个连接到MySQL数据库的C#Web应用程序。当多个用户同时访问该站点时,我们看到“已经有一个与此命令关联的开放数据读取器,必须先关闭”错误。只有一个人访问该网站时,该应用程序正常工作。应用程序上的并发用户导致MySQL数据库错误
我在连接字符串中发现了多个位于MultipleActiveResultSets = True的文章,但只适用于SQL Server而不是MySql。
我将错误追溯到我的runSQL函数,该函数处理大量数据库查询,但无法找到解决方案。
这是一个相当简单的功能,它需要原始的SQL代码的参数列表,这相当于许多可能的数据库连接字符串的一个枚举,并决定,如果我们需要建立事务的布尔。
我不知所措。
public DataTable runSQL(string QueryStr, List<MySqlParameter> Parameters, ConnectionType Connection, bool Transaction)
{
DataTable results = new DataTable();
MySqlConnection con = new MySqlConnection(getConnection(Connection));
MySqlTransation trans;
MySqlCommand command;
con.Open();
//if a transaction was requested, tie one to the query
if(Transaction)
{
trans = con.BeginTransaction();
command = new MySqlCommand(QueryStr, con, trans);
}
else
{
command = new MySqlCommand(QueryStr, con);
}
//if parameters were provided add them to the query
if(Parameters.Count > 0)
foreach(MySqlParameter parm in Parameters)
command.Parameters.Add(parm);
try
{
//send the command and get the results
MySqlReader rdr = command.ExecureReader();
//populate the column names
string columnName;
Type type;
foreach(DataViewRow row in rdr.GetSchemaTable().DefaultView)
{
columnName = row["ColumnName"].ToString();
type = (Type)row["DataType"];
results.Columns.Add(columnName, type);
}
//populate the results
results.Load(rdr);
//so far so good, close the transaction if one was requested
if(Transaction)
{
command.Transaction.Commit();
}
con.Close();
}
catch (Exception up)
{
//something bad happened, rollback if there was a transaction
if(Transaction)
{
command.Transaction.Rollback();
}
con.Close();
//report the error for handling at source.
throw up;
}
return results;
}
答
谢谢特拉维斯。
我刚刚通过使该函数成为静态并从数据库连接中删除单例模式来解决问题。我为了节省内存而构建它,但在这种情况下,它造成了更多的问题,而不是解决问题。
答
MySql中的并发性是一场噩梦。对不起,像这样开始,但如果它在所有可能的情况下都应该移植到MSSQL,因为你正在使用C#并且它非常容易集成。
使用MyISAM MySQL数据库引擎时,并发性特别差。首先,还有一个大红旗,就是MyISAM 不支持交易。这意味着您无法更改任何读取或更新的隔离级别。其次,与第一个相关的是,使用表上的读取发出低级表锁。但是,为了进行更新,它必须具有排它表锁,而其他任何(甚至是低级)锁都将防止发生这种情况,并且它将进入锁队列。
这是没有解决,因为它是由设计。