【问题标题】:Linq to SQL - Dirty Reads after Updating - WCF ServiceLinq to SQL - 更新后的脏读 - WCF 服务
【发布时间】:2011-12-02 08:46:35
【问题描述】:

我有一个 dbml 文件(linq to sql)来连接我的数据库。我有一个使用通用存储库(针对每个实体)与 dbml 对话的管理器。经理使用回购做工作(CRUD 操作)。 WCF 包装管理器并将其公开给外部世界(以便我的应用程序可以使用它)。

DB IRepository IManager(IRepo, IRepo...) WCFService(IManager)

我已经测试了经理,每次都能正常工作。问题是WCF。我将读取数据(例如 GetAllLocations),更新数据(例如更改位置名称),但稍后在某个随机点,我将读取脏数据。例如。如果我一直将位置名称从“BC 1”更改为“BC 2”,再更改为“BC 3”,有时我会阅读它并获取旧值。就像在我将其更改为“BC 3”并且我期待阅读“BC 3”之后,我得到“BC 1”(这没有意义,因为更新前的值无论如何都是“BC 2”)。默认情况下,WCF 没有缓存,为什么这发生在我的 WCF 上而不是我的经理上? WCF 所做的只是将值传递给管理器并从管理器获取值,它是一个非常基本的包装类。

注意:我正在使用 StructureMap 来自动解决 DependencyInjection 和 IoC 问题。

问题方法:正在读取的任何内容(例如 GetLocationById 和 GetAllLocations)。他们只是并不总是从数据库中返回最新数据。我知道这不是管理器,因为我创建了一个简单的项目来独立测试管理器和 WCF,并且只有 WCF 在更新数据后(特别是位置)有脏读。我还没有测试所有其他实体。

最后一点:我不断收到“System.Data.Linq.ChangeConflictException:未找到或更改行”。例外。我将 DBML 设计器位置实体的属性(PK 除外)更改为更新检查:从不。无论如何,脏读发生在此更改之前,并且管理器工作正常(并且它使用 DBML)。所以我没有理由相信这是导致脏读的原因。

此外,位置实体在数据库中有一个触发器,但我已将其排除为原因,因为我禁用了它并且没有帮助,并且经理再次正常工作。

【问题讨论】:

    标签: wcf web-services linq-to-sql


    【解决方案1】:

    有几件事可能会导致这种情况:

    • 环境事务范围的隔离级别,可能不同
    • 通过 WCF 的一个区别是通过 IIS 可能会导致事情同时运行

    你可以尝试的事情是:

    • 设置事务范围的隔离级别
    • 确保您的连接字符串启用 MARS - 多个活动结果集

    【讨论】:

    • 您建议将隔离级别设置为什么?我尝试将其设为 ReadCommitted,但在本地计算机上安装后无法启动该服务。
    • 我尝试在我的 dbml 连接字符串上启用 MARS,但没有帮助。
    • ReadCommitted 是停止脏读的最低级别。您的服务在使用时不会启动,这表明存在其他问题。你得到什么错误?检查事件日志
    • 感谢您的帮助,我解决了(结构映射缓存问题,只有在使用 WCF 时才变得明显)。
    【解决方案2】:

    原来这是使用 WCF 和结构映射引起的缓存问题。在数据注册表中注册数据上下文时,我更改了默认结构映射缓存。

    For<MyDataContext>()
       //.HybridHttpOrThreadLocalScoped()
       .Use(() => new MyDataContext());
    

    默认是每次调用,这是我需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 2012-01-26
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多