【问题标题】:Entity Framework Context Management实体框架上下文管理
【发布时间】:2011-06-13 21:14:35
【问题描述】:

我有一些关于实体框架上下文实例管理的问题。

我的代码库由许多独立的组件/代理组成,它们都在一个进程中运行,只能通过在方便时从相应队列中读取消息来工作(只要组件准备好,它就会从队列,因此在组件级别没有并发问题)

每个组件都需要独立于其他组件与数据库进行交互。我想知道为每个组件设置上下文实例的更好方法是什么。以下是一些选项

1> 拥有所有组件使用的上下文的一个实例。 --> 我认为这是最糟糕的,因为它会产生许多并发问题?

2> 给每个组件一个独立的上下文实例。 --> 这看起来不错,但是

  • 可以在一个进程中拥有多个上下文无关的实例,同时所有组件都在该进程中同时运行吗?

  • 我应该为组件将要处理的每条新消息创建一个新的上下文实例,还是在组件的生命周期内保留一个上下文实例?我认为最后一个更有意义,但我更习惯于在 using{} 括号中使用上下文,我不确定在每个组件的生命周期中保持一个上下文是否对我使用它的方式有任何复杂性?

  • 如果所有上下文都在一个进程中,我是否可以依赖乐观并发,以便两个不同的独立组件不会将相同的记录放入数据库中?

顺便说一句,我使用的是实体框架 4.1。

【问题讨论】:

    标签: entity-framework events entity-framework-4


    【解决方案1】:

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

    为什么:

    • 上下文内部使用了两个非常重要的设计模式——标识映射和工作单元。 This answer 描述了这些模式强制执行的行为。
    • EF 中的上下文和其他任何内容都不是线程安全的。

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

    【讨论】:

    • 感谢您的回答。如果我对每条消息使用一个上下文,那么在每个代理可以处理数百条消息的情况下,为每条消息创建和销毁每个上下文的成本是多少?另外,在 4.1 中我的上下文的两个实例之间有什么共享的吗?有什么事吗?
    • 不应该有任何显着的开销,即使有开销,如果您希望应用程序正常工作并使用 EF,您也别无选择。所有上下文在内部共享模型的描述 - 构建模型描述是非常昂贵的操作,因此它只构建一次并在所有上下文实例之间共享。
    • 另外,对于我在代理级别没有任何并发​​问题的场景(代理处理消息一一处理),每次每条消息创建上下文的价值是什么?我现在很清楚这样做没有问题,但仍然不清楚每条消息的新上下文的价值,而不是代理生命周期的上下文,因为在代理级别没有并发问题?换句话说,除了并发问题之外,每个请求的新上下文的价值是多少?
    • 该值可以是例如减少内存占用。除非您手动分离每个这样的实体,否则上下文会在内部引用它所使用的每个实体。此外,该值可以是您的应用程序的一致性。如果任何消息处理都出现问题并且您在上下文中存储任何内容而不保存更改,则下一条消息也将保存这些内容。此外,如果您在保存代理期间向上下文中添加任何导致异常的内容,那么您的代理将失效,因为如果不修复数据或重新创建上下文,您将无法保存其他任何内容。
    • 非常正确!感谢您的见解!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多