实体框架上下文管理

4
我有关于实体框架上下文实例管理的一些问题。
我的代码库由许多独立的组件/代理组成,它们都在同一个进程中运行,只能通过读取它们对应队列中的消息来执行工作(每当组件准备好时,它将获取队列中的下一条消息,因此在组件级别不存在并发问题)。
每个组件都需要独立于其他组件与数据库进行交互。我想知道为每个组件设置上下文实例的更好方法是什么。以下是一些选项:
1> 所有组件使用一个上下文实例。--> 我认为这是最糟糕的,因为它会创建许多并发问题?
2> 为每个组件提供独立的上下文实例。--> 这看起来不错,但是
- 在所有组件并发运行的情况下,在一个进程中拥有许多独立的上下文实例是否可行? - 对于每个组件将要处理的新消息,我应该创建一个新的上下文实例还是保持一个上下文实例的生命周期? 我认为后者更有意义,但我更习惯于在using{}括号中使用上下文,而且我不确定在我使用它的方式中保持一个上下文实例的生命周期是否有任何复杂性? - 我可以依赖于乐观并发性,以使两个不同的独立组件不会在数据库中放置相同的记录,假设所有上下文都在一个进程中?
顺便说一句,我正在使用实体框架4.1。
1个回答

3

建议对于每个组件/代理使用一个上下文 - 如果组件是多线程的,则对于每个线程使用一个上下文。如果每个消息处理都作为单独的“逻辑事务”执行,则对于每个消息处理使用一个上下文。

为什么:

  • 上下文内部使用两个非常重要的设计模式 - Identity map和Unit of work。 这个答案描述了这些模式所强制执行的行为。
  • 上下文和EF中的任何其他内容都不是线程安全的。

乐观并发并不意味着不同的上下文不会将相同的记录放入数据库中。乐观并发意味着更新语句将当前状态在数据库中与上下文的最后已知状态进行比较(在加载记录和保存新值之间存在延迟,另一个上下文可以更改记录)。如果记录更改,您将收到异常并且必须以某种方式处理它。


谢谢你的回答。如果我每条消息使用一个上下文,那么为每条消息创建和销毁上下文的成本是多少?考虑到每个agent可能需要处理数百条消息。另外,在4.1版本中,两个上下文实例之间是否有任何共享内容? - iCode
1
即使存在一些开销,如果想要应用程序正常运行并使用 EF,也不能有任何显著的额外开销。所有上下文都内部共享模型描述 - 构建模型描述是非常昂贵的操作,因此仅构建一次并在所有上下文实例之间共享。 - Ladislav Mrnka
此外,对于我没有任何代理级并发问题的情况(代理逐条处理消息),每次针对一条消息创建上下文的价值是什么?我现在很清楚这样做不会有任何问题,但仍然不清楚每个消息使用一个新上下文而不是为代理的整个生命周期创建一个上下文,除了并发问题之外还有什么价值?换句话说,每个请求使用一个新上下文的价值是什么? - iCode
该值可以例如减少内存占用。除非您手动分离每个实体,否则上下文将在内部引用它所使用的每个实体。此外,该值可以是应用程序的一致性。如果任何消息处理出现问题并且您在上下文中存储了任何内容而没有保存更改,则下一个消息也将保存此内容。此外,如果您添加到上下文中的任何内容在保存期间引发异常,则代理已死,因为在修复数据或重新创建上下文之前,您将无法保存其他任何内容。 - Ladislav Mrnka
非常正确!感谢您的见解! - iCode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接