【问题标题】:Dirty read concept in Entity Framework using C#使用 C# 的实体框架中的脏读概念
【发布时间】:2019-08-07 20:10:02
【问题描述】:

我正在使用实体框架和 C# 开发 Web API。我需要脏读的解决方案。

我尝试了以下方法和事务方法,我需要解决脏读的方法。

脏读或幻读是用户没有更新最新数据的现象。

假设用户 A 打开了推销员网页

用户B也打开了同一个推销员网页

A 加载了推销员 ID 1001,B 也加载了 1001 将推销员姓名更改为 X 并保存。

但是 B 看到的是旧数据,如果 B 将推销员姓名更改为 Y,A 的更改将被覆盖。所以我们应该阻止 B 将更改写入 DB。

所以我需要基于上述概念的解决方案。

using (var transaction = db.Database.BeginTransaction())
{
    try
    {
        db.SaveChanges();
        transaction.Commit();
    }
    catch (Exception excp)
    {
        throw excp;
    }
}

return Ok();

下面是我试过的代码

using (var transaction = db.Database.BeginTransaction())
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    KSTU_COUNTER_MASTER kcm = new KSTU_COUNTER_MASTER();
    kcm.obj_id = Common.GetNewGUID();
    kcm.company_code = Common.CompanyCode;
    kcm.branch_code = Common.BranchCode;
    kcm.counter_code = c.CounterCode;
    kcm.counter_name = c.CounterName;
    kcm.Maincounter_code = c.MaincounterCode;
    kcm.obj_status = c.ObjectStatus;
    kcm.UpdateOn = Framework.Common.GetDateTime();
    kcm.UniqRowID = Guid.NewGuid();

    db.KSTU_COUNTER_MASTER.Add(kcm);

    try
    {
        db.SaveChanges();
        transaction.Commit();
    }
    catch (Exception excp)
    {
        throw excp;
    }
}

return Ok();

【问题讨论】:

  • 这就是 SQL Server 中的 ROWVERSION 列类型(以及其他平台的类似结构)的用途:两个客户端都读取带有核心数据的行版本,当他们去更新时,SQL Server会自动增加行版本。如果有问题的行仍然具有他们已读取的行版本,则两个客户端都必须在更新之前 检查 - 如果 not (例如在您的场景中用户 B 的情况) ,则更新不得应用(也称为“乐观并发处理”)
  • 谢谢你的回答..我知道这个概念,但请帮助我解决方案代码..
  • 这不是脏读。脏读是指允许用户读取第二个事务中未提交的数据。 SQL 服务默认为 READ COMMITTED 隔离,因此除非您更改了事务隔离级别,否则您不能有脏读。你说的是乐观并发。
  • 这里是 ef6 中optimistic concurrency 的教程

标签: c# entity-framework asp.net-web-api concurrency dirtyread


【解决方案1】:

假设用户 A 打开了推销员网页 用户B也打开了同一个推销员网页 A 已加载推销员 ID 1001,B 也加载 1001 A 将推销员名称更改为 X 并保存。

cmets 是正确的,这是一个需要客户端乐观并发检查的问题,而不是数据库事务。但我想解释为什么会这样。

您实际上可以在此处使用事务,在 SNAPSHOT、REPEATABLE READ 或 SERIALIZABLE 隔离级别。 A 和 B 都可以打开同一个推销员页面并进行编辑,但无论哪一个尝试保存 last 都会导致错误(此错误可能是死锁,具体取决于隔离级别)。但是会防止写覆盖异常。

但是,要完成这项工作,您必须保持数据库连接,并且从每个用户导航到“推销员网页”到用户保存数据的时间,事务都处于打开状态。在 Web 应用程序中,您没有关于或控制多长时间的信息。在客户端-服务器应用程序中,您可以在某种程度上完成这项工作,但在 Web 应用程序中,这种方法几乎被普遍抛弃,取而代之的是客户端乐观并发。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多