1

我想做一些压力测试来模拟我的应用程序的多用户环境。我们使用实体框架 (EF) 作为我们的 ORM,使用 SQL Server 2008 R2 Enterprise 作为我们的后端。

这是模型的一部分 - 每个对象 ( NodeBase) 都有Metadatum对象 - 1:1 映射。似乎NodeBase是首先写入,然后是Metadatum第二个对象(或与Metadatum对象的关联,不确定)。无论哪种方式,当我执行搜索时,我都会拉起 a NodeBase,但它Metadatum是空的。5 秒后,同样的搜索发现了该Metadatum对象。:-/。令人沮丧。

在此处输入图像描述

在我的测试中,我有 2 个实例运行我们的应用程序(用于读取的 GUI,以及用于 R/W 的单元测试)。单元测试锤击数据库,创建对象的最坏情况读取和写入,GUI 正在读取数据库发生的所有更改(通过请求新数据锤击数据库)。

在此处输入图像描述

问题似乎是我的搜索引擎正在读取一个新写入的对象,并在对象的子对象和写入之前对其进行处理。当搜索去处理孩子时,有一个空异常。如果搜索等待几秒钟(没有比DateTime.Now.AddSeconds(-5)看起来运行良好的更新),一切都会好起来的。虽然这适用于我当前的特定问题,但我怀疑它不会出现在应用程序的其他地方。

我试过的:

  1. 我编写代码中的事务(我可能没有所有选项都正确,或者可能做错了),但这似乎没有任何效果。每次写入都使用此事务:

        using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.Serializable}))
        {
            ContainerResult = OasisModelContainer.SaveChanges(false);
            OasisModelContainer.AcceptAllChanges();
            transactionScope.Complete();
        }
    
  2. 尝试先在单独的数据库上下文中将我的子对象抢先写入数据库,释放上下文,在当前上下文中重新读取子对象,附加到父对象(在事务中),但这不起作用.

  3. 其他只是闲逛的东西,关于 Stack Overflow 的提示等。

  4. 我尝试使用快照,但我不确定我是否正确使用它 - 我在我的数据库上设置了它:

    ALTER DATABASE [ObjectModel] SET ALLOW_SNAPSHOT_ISOLATION ON 
    ALTER DATABASE [ObjectModel] SET READ_COMMITTED_SNAPSHOT ON
    

我在想什么:

  1. 将 WriteLock 布尔值添加到在写入期间设置的每个对象,并且任何时候读取对象时,只有在清除 WriteLock 时才会继续。这具有巨大的影响(重构大量代码),并且不是可取的。

  2. 读取期间轮询 - 如果子对象为 Null,则延迟,再试一次。再次,潜在的巨大重构。

  3. 在写入期间向数据库添加表/数据库锁。我对 SQL Server 知之甚少,不知道这是聪明还是愚蠢。你能以不会导致死锁的方式锁定数据库或表吗?您可以设置 SQL Server 死锁超时,以便客户端应用程序不会超时吗?

任何帮助/指针/建议将不胜感激!

4

0 回答 0