我想做一些压力测试来模拟我的应用程序的多用户环境。我们使用实体框架(EF)作为我们的ORM,使用SQL Server 2008 R2 Enterprise作为我们的后端。
这是模型的一部分 - 每个对象(NodeBase
)都有Metadatum
个对象 - 1:1映射。似乎首先写入NodeBase
,然后写入Metadatum
对象第2(或与Metadatum
对象的关联,不确定)。无论哪种方式,当我执行搜索时,我都会调出NodeBase
,但Metadatum
为空。 5秒后,相同的搜索显示Metadatum
对象。 : - /。令人沮丧。
在我的测试中,我有2个实例运行我们的应用程序(用于读取的GUI和用于R / W的单元测试)。单元测试锤击数据库,创建最坏情况的场景读数&写入对象,GUI正在读取发生在DB上的所有更改(通过请求新数据来破坏数据库)。
问题似乎是我的搜索引擎正在读取一个新写入的对象,并在对象的子对象之前处理它。当搜索处理子进程时,会有一个null异常。如果搜索等了几秒钟(没有什么比DateTime.Now.AddSeconds(-5)
更新似乎运行良好),一切都会好的。虽然这适用于我当前特定的问题,但我怀疑它不会出现在应用程序的其他位置。
我尝试了什么:
我的编写代码中的事务(我可能没有正确的选项,或者可能做错了),但这似乎没有任何影响。每次写入都使用此事务:
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.Serializable}))
{
ContainerResult = OasisModelContainer.SaveChanges(false);
OasisModelContainer.AcceptAllChanges();
transactionScope.Complete();
}
首先尝试先将我的子对象写入数据库,在单独的数据库上下文中,处理上下文,在当前上下文中重新读取子对象,附加到父对象(在事务中),但这不起作用。
其他只是四处寻找的东西,Stack Overflow的提示等等。
我尝试使用快照,虽然我不确定我是否正确使用它 - 我在我的数据库上设置了这个:
ALTER DATABASE [ObjectModel] SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE [ObjectModel] SET READ_COMMITTED_SNAPSHOT ON
我在想什么:
将WriteLock布尔值添加到写入期间设置的每个对象,并且只要读取了对象,它就会在清除WriteLock时继续。这有很大的影响(重构很多代码),并不是优选的。
读取期间轮询 - 如果子对象为空,则延迟,请重试。再次,可能是巨大的重构。
在写入期间向数据库添加表/数据库锁。我不太了解SQL Server知道这是聪明还是愚蠢。你可以锁定数据库或表,以免它导致死锁吗?您是否可以设置SQL Server死锁超时,以便客户端应用程序不会超时?
非常感谢任何帮助/指示/建议!