ORM 中的跟踪数据如何保持最新?
Posted
技术标签:
【中文标题】ORM 中的跟踪数据如何保持最新?【英文标题】:How is tracked data in an ORM kept up to date? 【发布时间】:2019-03-14 19:35:29 【问题描述】:当数据更改可能来自其他来源时,Entity Framework 之类的东西如何跟踪其数据的更改?例如:当有一个相同的 asp net core 应用程序的集群在运行时,如果一个应用程序更新了一条记录,但它正在另一个实例上被跟踪,并且该实例接收到一个 get 请求,它不会发送过期数据吗?
基本上,如果 ORM 执行本地更改跟踪,它们如何保持 ACIDity?
【问题讨论】:
简单(也是唯一)的答案是:不是。 EF 不会以任何方式跟踪来自其他来源的更改。该地区没有任何东西是自动化的。 【参考方案1】:将 EF 上下文及其本地缓存视为短暂存在会有所帮助。当您读取一个实体时,该实体的“生命周期”应该被认为与创建它的 DbContext 的生命周期相匹配。在该生命周期之外,该对象实际上被假定为与任何其他可能陈旧的数据副本一样。即使在该生命周期内,它也不会与底层数据源同步,因此关键在于何时调用 SaveChanges
。 EF 提供的缓存更多地围绕以下场景:“我将加载一些实体,这些实体引用其他实体。当代码迭代实体时,当遇到对其他内容的引用时,EF 将检查看看其他东西是否已经加载并在去数据库之前提供它。”因此,从这个意义上说,长期存在的 DbContext 是一件坏事,因为其中一些缓存数据可能非常陈旧和陈旧,并且随着 DbContext 加载更多数据,筛选这些跟踪实体会变得更慢,并且上下文会消耗更多内存。
在 Web 应用程序中,DbContext 通常限定为单个请求,或者比该请求更短。 (工作单元)这意味着对同时处理的请求的编辑不会被通知彼此的更改,并且在这些请求上下文加载其数据并准备保存的时间之间,两个请求都不会看到其他源所做的更改。 EF 可以知道要检查并发更改的内容,通常是行版本时间戳,并且可以阻止此检查失败的更新。除此之外,开发人员必须确定要采取的行动。这通常意味着捕获并发错误,然后移交给适当的处理程序以记录详细信息并通知用户。这可能是先入胜出的场景,通知用户他们的更改失败并重试; (提供刷新的数据)Last-in-wins 场景,提示用户已更改但可以覆盖; (并希望记录事件以防出现争议/问题)或合并,系统检查更改并提供任何冲突和更改的详细信息供用户查看和调整/接受/或取消他们的更新。
EF 可以帮助检测到这一点,但最终开发人员必须编写代码来处理它。
就检测发生的并发编辑而言,这需要经过深思熟虑的编码来执行诸如在会话之间传达更改(发布/订阅),其中每个会话侦听其正在积极处理的实体的更新,并在实体发生更改时广播更改更新它们。检测其他来源可能对数据进行的其他更改意味着另一个进程来侦听数据库更新(超出系统已经知道的更改)并将这些更改通知广播到任何活动会话。看到实际工作当然是一件很酷的事情,但它所带来的成本和复杂性必须证明是合理的,而不仅仅是处理保存时的并发问题。 :)
【讨论】:
嗯...在这种情况下,我看不到在我的项目中使用完整的 ORM(例如 EF)的任何理由。在我看来,好处在于易于以面向对象的方式表达业务逻辑,这可以通过诸如 Dapper 之类的微 ORM 来满足,同时保留 ADO.Net 驱动程序的原始性能。以上是关于ORM 中的跟踪数据如何保持最新?的主要内容,如果未能解决你的问题,请参考以下文章