当数据更改可能源自其他来源时,诸如Entity Framework之类的方法如何跟踪其数据更改?例如:如果有一个运行同一asp net核心应用程序的群集,并且一个应用程序更新了一条记录,但是正在另一个实例上对其进行跟踪,并且该实例收到一个get请求,它会发送过期数据吗? >
基本上,如果ORM执行本地变更跟踪,如何保持ACIDity?
答案 0 :(得分:0)
这有助于考虑EF上下文及其本地缓存,尤其是短暂的。当您读取一个实体时,应将该实体的“寿命”视为与起源该实体的DbContext的寿命相匹配。超过该寿命,实际上仅假定该对象与数据的任何其他可能过时的副本一样。即使在该生命周期内,它也不会与基础数据源同步,因此,要点是何时调用SaveChanges
。 EF提供的缓存更多地围绕以下场景:“我将加载一些实体,这些实体引用其他实体。随着代码在这些实体上迭代,当遇到对其他对象的引用时,EF将检查以下内容:请先查看是否已经加载了其他内容,然后再发送给数据库。”因此,从这个意义上讲,长期存在的DbContext是一件坏事,因为其中一些缓存的数据可能已经很旧并且过时,并且随着DbContext加载更多的数据,通过这些跟踪的实体进行筛选变得越来越慢,并且上下文消耗了更多的内存。 >
在Web应用程序中,DbContext的作用域通常是单个请求或更短。 (工作单元)这意味着不会同时通知对并发处理的请求的更改,并且在这些请求上下文加载其数据并准备保存之间,两个请求都不会看到其他源所做的更改。 EF可以知道要检查的并发更改(通常为行版本时间戳),并且可以阻止此检查失败的更新。除此之外,开发人员还必须确定要采取的措施。这通常意味着捕获并发错误,然后移交给适当的处理程序以记录详细信息并通知用户。这可能是双赢的方案,其中通知用户其更改失败并重试。 (提供刷新的数据)最终制胜方案,提示用户进行了更改但可以覆盖; (并希望在有争议/问题的情况下记录该事件)或合并,系统将检查更改并提供任何冲突和更改的详细信息,以供用户查看和调整/接受/或取消其更新。
EF可以帮助检测到这一点,但是最终开发人员必须编写代码来解决该问题。
就检测并发编辑时而言,这需要进行有意识的编码,以执行诸如在会话之间进行更改通信(发布/订阅)的工作,其中每个会话都监听其正在工作的实体的更新,并在更改时向实体广播更改更新它们。要检测其他来源可能对数据进行的其他更改,意味着需要另一个过程来监听数据库更新(超出系统已经知道的更改),并将这些更改通知广播到任何活动的会话。看到要付诸实践,这确实是一件很酷的事情,但是它所带来的成本和复杂性不仅要在保存时处理并发问题,还必须要有道理。 :)