C# EF4 ObjectContext.SaveChanges是否线程安全?

C# EF4 ObjectContext.SaveChanges是否线程安全?,c#,entity-framework,thread-safety,savechanges,C#,Entity Framework,Thread Safety,Savechanges,我通过实体框架4访问我的数据库 我有一个服务器监听端口,等待一些消息。当一条消息出现时,它将被转换为一个表行,并且应该被插入到数据库中。但是,可以同时发送多条消息。对于每条消息,我创建一个任务(来自TPL)并异步执行它 这些任务中的每一个都会创建ObjectContext的实例,创建相应实体类的对象(表示数据库中的表),将数据插入ObjectContext,然后调用SaveChanges方法 因此,每个线程都创建了自己的ObjectContext。 ObjectContext的实例能否影响Obj

我通过实体框架4访问我的数据库

我有一个服务器监听端口,等待一些消息。当一条消息出现时,它将被转换为一个表行,并且应该被插入到数据库中。但是,可以同时发送多条消息。对于每条消息,我创建一个任务(来自TPL)并异步执行它

这些任务中的每一个都会创建ObjectContext的实例,创建相应实体类的对象(表示数据库中的表),将数据插入ObjectContext,然后调用SaveChanges方法

因此,每个线程都创建了自己的ObjectContext。 ObjectContext的实例能否影响ObjectContext的任何其他实例? 这种情况会有副作用吗


(请注意,插入的数据不会产生任何引用完整性错误)。

数据上下文通常不是线程安全的;但因为它们都是独立的(每个请求),所以这不是问题


过于简单的答案是“不”,因为上下文是不相关的。但是,与数据库对话的任何内容都可能有边缘条件,这取决于在执行
保存更改之前运行的查询,以及任何内容是否为幻象或不可重复读取,或者是否有任何内容正在更新也已由另一个请求更新的数据,或者对不同的请求分别进行两次插入就可以了,但组合起来会违反唯一约束,等等。

数据上下文通常不是线程安全的;但因为它们都是独立的(每个请求),所以这不是问题


过于简单的答案是“不”,因为上下文是不相关的。但是,与数据库对话的任何内容都可能有边缘条件,这取决于在执行
保存更改之前运行的查询,以及任何内容是否为幻象或不可重复读取,或者是否有任何内容正在更新也已由另一个请求更新的数据,或者对不同的请求分别进行两次插入,这样可以,但组合起来会违反唯一约束,等等。

在您的情况下,事务完整性由数据库(SQL Server)而不是实体框架来保证。因为每个线程都有自己的上下文,所以您不必担心每个上下文的
SaveChanges()
会干扰另一个线程


ObjectContext
的一个实例不能影响另一个实例。您可能会遇到这样的情况:一个
SaveChanges()
修改数据库的方式会导致其他上下文上的后续
SaveChanges()
失败。但这是出于设计,也是SQL Server强制执行其约束的结果。

在您的情况下,事务完整性是由数据库(SQL Server)而不是实体框架保证的。因为每个线程都有自己的上下文,所以您不必担心每个上下文的
SaveChanges()
会干扰另一个线程


ObjectContext
的一个实例不能影响另一个实例。您可能会遇到这样的情况:一个
SaveChanges()
修改数据库的方式会导致其他上下文上的后续
SaveChanges()
失败。但这是出于设计,也是SQL Server强制执行其约束的结果。

行是否有时间戳列?如果是这样,在处理ObjectContext的不同实例时可能会遇到并发异常。这并不能回答您关于线程安全的问题,但它可能会导致错误。我不确定为什么时间戳列会导致错误。想用一两句话详细说明一下吗?他们确实有一个timestamp列,但这与EF没有任何关系,我想EF应该像对待任何其他列一样对待这一列(这不是键)。对不起,因为您只做插入,这不重要。但是,如果有任何更新,请考虑一下:CordExt1和CordExt2都是用TimeSTAMP1打开的。Context1保存,更新为timestamp2。当Context2保存时,其时间戳1将与新读取的时间戳2不匹配,从而引发并发异常。好的,这是预期的。我知道这个问题,但这在我的场景中不是问题,正如您已经注意到的,我只插入数据。您的行有时间戳列吗?如果是这样,在处理ObjectContext的不同实例时可能会遇到并发异常。这并不能回答您关于线程安全的问题,但它可能会导致错误。我不确定为什么时间戳列会导致错误。想用一两句话详细说明一下吗?他们确实有一个timestamp列,但这与EF没有任何关系,我想EF应该像对待任何其他列一样对待这一列(这不是键)。对不起,因为您只做插入,这不重要。但是,如果有任何更新,请考虑一下:CordExt1和CordExt2都是用TimeSTAMP1打开的。Context1保存,更新为timestamp2。当Context2保存时,其时间戳1将与新读取的时间戳2不匹配,从而引发并发异常。好的,这是预期的。我知道这个问题,但这在我的场景中不是问题,正如您已经注意到的,我只插入数据。但是您的副作用实际上是由数据库引起的,而不是EF。我对这里的意思理解正确吗?因此,基本上EF只执行SQL查询,以更改当前加载的数据定义的DB状态和调用SaveChanges()时的DB状态。如果可以在SQL server不引起错误的情况下进行此类更改,EF将成功(连接或其他问题放在一边)。。。是吗?是的;只要数据库不抱怨,你没有任何其他不安全的事情你没有提到-那么EF在不同的上下文中不会引起问题。但是你的副作用实际上是由数据库引起的-不是EF。我对你在这里的意思理解正确吗?那么打电话吧