首页 > 解决方案 > ORM 中的跟踪数据如何保持最新?

问题描述

当数据更改可能来自其他来源时,诸如实体框架之类的东西如何跟踪其数据的更改?例如:当有一个相同的 asp net core 应用程序集群正在运行并且一个应用程序更新了一条记录但它正在另一个实例上被跟踪并且该实例接收到一个获取请求时,它不会发送过时的数据吗?

基本上,如果 ORM 执行本地更改跟踪,它们如何保持 ACIDity?

标签: entity-frameworkorm

解决方案


将 EF 上下文及其本地缓存视为短暂存在会有所帮助。当您读取一个实体时,该实体的“生命周期”应该被认为与创建它的 DbContext 的生命周期相匹配。在该生命周期之外,该对象实际上被假定为与任何其他可能过时的数据副本一样。即使在那个生命周期内,它也不会与底层数据源同步,所以关键是什么时候SaveChanges叫做。EF 提供的缓存更多地围绕以下场景:“我将加载一些实体,这些实体引用其他实体。当代码迭代实体时,当遇到对其他内容的引用时,EF 将检查看看其他东西是否已经加载并在去数据库之前提供它。” 所以从这个意义上说,长期存在的 DbContext 是一件坏事,因为其中一些缓存数据可能非常陈旧和陈旧,并且随着 DbContext 加载更多数据,筛选这些跟踪实体变得更慢,并且上下文消耗更多内存。

在 Web 应用程序中,DbContext 通常限定为单个请求,或者更短。(工作单元)这意味着在同时处理的请求上的编辑不会被通知彼此的更改,并且在这些请求上下文加载其数据并准备保存的时间之间,两个请求都不会看到其他源所做的更改。EF 可以知道要检查并发更改的内容,通常是行版本时间戳,并且可以在此检查失败时阻止更新。除此之外,开发人员必须确定要采取的行动。这通常意味着捕获并发错误,然后移交给适当的处理程序以记录详细信息并通知用户。这可能是先入胜出的场景,通知用户他们的更改失败并重试;(提供刷新的数据)Last-in-wins 场景,提示用户已更改但可以覆盖;(并希望记录事件以防出现争议/问题)或合并,系统检查更改并提供任何冲突和更改的详细信息供用户查看和调整/接受/或取消他们的更新。

EF 可以帮助检测到这一点,但最终开发人员必须编写代码来处理它。

就在发生时检测并发编辑而言,这需要经过深思熟虑的编码来做一些事情,例如在会话(发布/订阅)之间传达更改,其中每个会话侦听其正在积极处理的实体的更新,并在更新实体时将更改广播给实体。检测其他来源可能对数据进行的其他更改意味着另一个进程来侦听数据库更新(超出系统已经知道的更改)并将这些更改通知广播到任何活动会话。看到实际工作当然是一件很酷的事情,但它引入的成本和复杂性必须证明是合理的,而不仅仅是处理保存时的并发问题。:)


推荐阅读