应用程序上的并发用户导致MySQL数据库错误

时间:2014-12-05 22:28:57

标签: c# mysql multiple-users

我有一个连接到MySQL数据库的C#Web应用程序。当多个用户同时访问该站点时,我们看到“已经有一个与此命令关联的打开的datareader必须先关闭”错误。当只有一个人访问该网站时,该应用程序正常工作。

我发现在连接字符串中有多篇文章选中了MultipleActiveResultSets = True,但这只适用于SQL Server而不是MySql。

我将错误跟踪到我的runSQL函数,该函数处理大量数据库查询但无法找到解决方案。

这是一个相当直接的功能,它需要原始的sql代码,一个参数列表,一个转换为许多可能的数据库连接字符串之一的枚举,以及一​​个确定我们是否需要设置事务的bool。

我不知所措。

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;
}

2 个答案:

答案 0 :(得分:0)

MySql中的并发是一场噩梦。很抱歉这样开始,但如果可能的话,你应该移植到MSSQL,因为你使用的是c#,它很容易集成。

使用MyISAM MySQL数据库引擎时,并发性特别差。首先,还有一个大红旗,是MyISAM 不支持交易。这意味着您无法更改任何读取或更新的隔离级别。第二,与第一个相关的是,使用表上的读取发出低级表锁。但是,为了进行更新,它必须具有独占表锁,并且其他任何内容(甚至是低级别)都将阻止这种情况发生,并且它将进入锁定队列。

没有解决这个问题,因为它是设计的。

答案 1 :(得分:0)

谢谢特拉维斯。

我刚刚通过使函数静态并从数据库连接中删除单例模式来解决问题。我以这种方式构建它以节省内存,但在这种情况下它引起的问题比它解决的更多。

相关问题