并发数据库访问期间的错误 - 竞争条件?

时间:2017-08-17 06:08:36

标签: c# sql mariadb race-condition

我们的应用程序遇到了麻烦,这个应用程序同时被近500人使用。它是一个Windows桌面应用程序,它在后台使用单个数据库来存储数据。似乎有时会出现一些我们无法再现的竞争条件。当选择更新错误的ID时,例如更新错误的数据。

protected static void ExecuteNonQuery(MySqlConnection connection, String statement, OptionalOut<int> outResult = null)
{
    var cmd = connection.CreateCommand();
    var cmd2 = connection.CreateCommand();
    cmd.CommandText = statement;
    cmd.CommandTimeout = 30;

    MySqlTransaction tran = null;
    MySqlDataReader reader = null;
    try
    {

        connection.Open();
        tran = connection.BeginTransaction(IsolationLevel.Serializable);
        cmd.ExecuteNonQuery();
        if (statement.ToUpper().StartsWith("INSERT INTO"))
        {
            if (outResult == null) outResult = new OptionalOut<int>();
            cmd2.CommandText = "SELECT LAST_INSERT_ID() AS last_ID";
            cmd2.CommandTimeout = 30;
            reader = cmd2.ExecuteReader();
            var ret = ConvertToDataSet(reader);
            var cells = ret.Tables[0].Rows[0][0];
            outResult.Result = Convert.ToInt32(cells);
            reader.Close();
        }
        tran.Commit();
        connection.Close();
    }
    catch (Exception e)
    {
        if (reader != null && !reader.IsClosed)
            reader.Close();
        if (tran != null && connection.State != ConnectionState.Closed && connection.State != ConnectionState.Broken)
            tran.Rollback();

        connection.Close();

        throw;
    }
}

这种方法有问题吗?我是否需要一些额外的锁定机制或参数IsolationLevel.Serializable是否足够?我需要做些什么来防止种族条件的每一种可能情况?

编辑:另一个奇怪的问题是,当一行正在更新并且某些内容失败时,其他列会被更改,但不会受到影响。这是随机发生的,一般来说SQL工作正常!

例如,客户获得要约(要约是客户表中的外键),要约状态从None切换到OfferReceived。员工接受要约并保存,数据库中的客户行不再有报价,报价状态切换为OfferAccepted。对此有任何解释吗?

0 个答案:

没有答案