在asp.net Web应用程序中使用mutex进行并发

时间:2018-06-04 12:35:33

标签: asp.net concurrency mutex

我正在编写一个Web应用程序,它必须将多个Microsoft Access数据库(由旧的Windows可执行文件使用)转换为一个MySQL数据库(由该程序的新在线版本使用)。在这个过程中,我正在转换具有int作为主键(PK,而不是自动增量)和文本字段(TX,而不是唯一)的表,因此每个PK具有一个特定的TX但是一个TX可以具有许多PK值(don不问。这些表的很大一部分在所有Access数据库中都是相同的。

多个用户应该能够同时转换多个数据库。 我做了以下事情:

private static Mutex mx = new Mutex();
protected void ConvertTable()
{
    // mx.WaitOne();
    var db = new dbXYZ();
    try
    {
        // Select old records from DataSet that holds all MS Access tables
        var source = from [...] select a;
        foreach (...)
        {
            // mx.WaitOne();

            // Search oldTX in new MySQL table
            var rec = (from [...] where TX=oldTX orderby PK select b).FirstOrDefault();
            if (rec == null)
            {
                rec = new XYZ();
                rec.TX = oldTX;

                // Search oldPK in new MySQL table
                var pk = (from [...] where PK=oldPK select c).FirstOrDefault();
                if (pk != null)
                    rec.PK = GenerateNewPK();
                else
                    rec.PK = oldPK;

                // Add record and update MySQL immediately
                db.XYZ.Add(rec);
                db.SaveChanges();
            }
            // Temporarily remember relation old/new PK for further processing
            pkTable[oldPK] = rec.PK;

            // mx.Release();
        }
    }
    catch
    {
        ...
    }
    // mx.Release();
}

上述函数由转换类封装,当用户单击上载的MS Access数据库的链接时调用该转换类:

Task t = Task.Factory.StartNew(() =>
{
    ConvClass conv = new ConvClass(DatabaseID, UploadPath);
}, TaskCreationOptions.LongRunning);

我添加了LongRunning选项,因为我理解在这种情况下,每个StartNew调用都会使用一个完整的单独线程。一个Access数据库的完整转换大约需要10-15分钟。

当同一个用户转换多个数据库并且我没有启用任何互斥锁调用时,会出现重复的PK错误。正如所料。

当同一个用户正在转换多个数据库并且我取消注释OUTER互斥锁调用时,并发转换在进入此函数时会相互等待。一切顺利,没有重复的PK错误。正如预期的那样。

但是当同一个用户正在转换多个数据库并且我取消注释INNER互斥锁调用时,我再次看到重复的PK错误。让用户逐个转换数据库(使用外部互斥锁调用)并不是那么糟糕但我想知道为什么这不起作用。

有谁可以告诉我为什么后者不起作用?

并且,当有多个用户(正在转换多个数据库)时,是否还需要考虑其他因素?

0 个答案:

没有答案