首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何分离并行请求?

如何分离并行请求?
EN

Stack Overflow用户
提问于 2013-03-27 06:07:34
回答 1查看 71关注 0票数 1

我将尝试用一个简化的控制台应用程序示例来解释这个问题,但是真正的项目是一个ASP.NET MVC3应用程序。

有以下表格:

想象一下以下场景:

  1. 用户创建一个报表( TestReport中的一行,其中Text是报表string内容,而Ready是一个bool标志,表示如果报表已经准备好要处理);默认情况下,Ready设置为false,即未准备就绪。
  2. 用户希望处理报告,所以他提交了报告;此处将Ready设置为true

如果尚未处理该报告,则该系统将有机会将其召回。因此,当报告被召回时,Ready设置为false返回。相反,在处理报表时,会在TestReportRef中创建一行,引用其Id的报告。

现在想象一下在同一时刻

  1. 用户想要召回报告;
  2. 将报告添加到进程列表中;

一旦这种情况同时发生,就可能发生错误。也就是说,报告将包含Ready == false,并将在TestReportRef中引用。

下面是一个简单的控制台示例,说明这种情况是如何发生的:

代码语言:javascript
复制
var dc = new TestDataContext('my connection string');
dc.TestReport.InsertOnSubmit(new TestReport
{
    Text = "My report content",
    Ready = true //ready at once
});
dc.SubmitChanges();

Action recallReport = () =>
{
    var _dc = new TestDataContext(cs);
    var report = _dc.TestReport.FirstOrDefault(t => t.Ready);
    if (report != null && !report.TestReportRef.Any())
    {
        Thread.Sleep(1000);
        report.Ready = false;
        _dc.SubmitChanges();
    }
};

Action acceptReport = () =>
{
    var _dc = new TestDataContext(cs);
    var report = _dc.TestReport.FirstOrDefault(t => t.Ready);
    if (report != null && !report.TestReportRef.Any())
    {
        Thread.Sleep(1000);
        _dc.TestReportRef.InsertOnSubmit(new TestReportRef
        {
            FK_ReportId = report.Id
        });
        _dc.SubmitChanges();
    }
};

var task1 = new Task(recallReport);
var task2 = new Task(acceptReport);

task1.Start();
task2.Start();

task1.Wait();
task2.Wait();

foreach (var t in dc.TestReport)
{
    Console.WriteLine(string.Format("{0}\t{1}\t{2}", t.Id, t.Text, t.Ready));
}

foreach (var t in dc.TestReportRef)
{
    Console.WriteLine("ref id:\t" + t.FK_ReportId);
}

添加Thread.Sleep(1000);以确保任务将检查一个和相同的情况。

给出的例子可能听起来很尴尬,但是,我希望它能解释我正在处理的问题。

我怎么才能避免这种情况?让存储库单独使用似乎不是个好主意。我是否应该使用一些共享互斥(一个用于所有web请求)来分离写操作?还是在这种情况下应该使用的模式?

这只是我的一个场景的一个简化例子。然而,有几种情况下,它可能会遇到类似的差异。我想最好的办法就是让这样的交叉点变得不可能。

EN

回答 1

Stack Overflow用户

发布于 2013-03-27 06:21:27

为什么不在报告表中添加一个version列?任务从跟踪当前版本开始,当任务结束时,如果该版本与跟踪版本相同,则操作正常,否则失败。如果操作显示正常,则将版本更新为版本+1。这是一种乐观锁;这意味着可能会发生冲突,但冲突并不频繁。

更新

如果您正在使用linqto,那么您可以在参数UpdateCheck [Column(UpdateCheck=UpdateCheck.Always)]上检查一下,在您的情况下,这对于处理并发性很有用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15652828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档