.NET ORM 更好地支持多线程?

Posted

技术标签:

【中文标题】.NET ORM 更好地支持多线程?【英文标题】:.NET ORM that supports multithreading better? 【发布时间】:2010-12-04 13:30:57 【问题描述】:

我知道有关 .net ORM 的问题已经被问了数千次,但我想知道哪种 ORM 在多线程环境中易于使用。欢迎商业或免费。

目前,我正在使用 Devexpress 的 XPO,但我觉得在多线程应用程序中使用起来很尴尬。一个线程的对象不能被另一个线程共享,要在另一个线程中使用它,我必须使用密钥从数据库中找到对象,这真的很烦人。即使您锁定了对象的状态,也无法将 DB 对象的状态持久化到 DB。例如除了创建对象的线程之外,不能从另一个线程调用 Save() 方法。

顺便说一句,我刚刚开始使用 XPO,也许我用错了。

【问题讨论】:

每当您开始跨线程共享对象时,您都会遇到问题。无论 ORM 支持如何,您都需要实现自己的锁定。 每个 O/RM 都可以在多线程环境中使用。所以请解释你想要做什么。使用什么样的多线程环境以及以何种方式使用。 【参考方案1】:

nHibernate 已在许多应用程序中使用,其中一些是多线程的。

请参阅concurrency 上的文档,特别是10.2 部分 - 它清楚地表明ISession 不是线程安全的(因此您需要自己管理)。

就您而言,您能否澄清一下什么会使 ORM “易于工作”?

【讨论】:

即使有锁定,对象在 XPO 中也是不可共享的,你只是不能从另一个线程调用 save()。【参考方案2】:

每个 O/RM 在多线程应用程序中都能完美运行。我在 ASP.NET 应用程序中使用了 LINQ to SQL 和 Entity Framework(每个定义都是多线程的)。

如果您在多线程环境中使用 O/RM 时遇到问题,那么您可能使用错了。例如,大多数 O/RM 工具都有一种实现工作单元模式的类型(例如 LINQ to SQL 的 DataContext、Entity Framework 的 ObjectContext 和 XPO 的 Session)。一个工作单元意味着由单个线程创建和控制。如果你以这种方式使用这样的对象,我在多线程环境中使用 O/RM 工具从来没有遇到过任何问题。

【讨论】:

可以说每个 O/RM 在多线程应用程序中都能完美运行。 @Spolto:说出一个没有的名字。 Entity Framework 4. 如果在单独的线程中使用对象上下文足够长的时间,数据很容易变得陈旧。 Oded 引用的 NHibernate。您说得对,它们通常设计为以单线程方式使用。 没有一个 O/RM 框架具有线程安全的工作单元,但这并不意味着框架本身不能用于多线程应用程序。【参考方案3】:

Entity Framework 中的 ObjectContext 既不是线程安全的,所以如果你想将它作为共享资源,你可能必须自己实现并锁定它。

您可以为每个线程创建一个新的对象上下文,但如果您有很多线程正在生成/终止,这很容易成为性能问题。

此外,每个线程都有一个 ObjectContext 可能会导致数据过时。如下所述:

最后但并非最不重要的当然是多用户并发问题。 ObjectContext 永远缓存它的实体,直到它被释放。如果另一个用户在他自己的 ObjectContext 上更改了相同的实体,则第一个 ObjectContext 的所有者将永远不会发现该更改。这些陈旧数据问题可能非常难以调试,因为您实际上可以看到查询进入数据库并返回新数据,但 ObjectContext 会用缓存中已经存在的旧数据覆盖它。在我看来,这可能是避免使用长寿命 ObjectContext 实例的最重要原因;即使您认为您已经对其进行了编码以从数据库中获取最新数据,ObjectContext 也会确定它比您更聪明,并把旧实体交还给您。

Entity Framework Object Context in ASP.NET Session object?

【讨论】:

以上是关于.NET ORM 更好地支持多线程?的主要内容,如果未能解决你的问题,请参考以下文章

[Java]多线程

.NET面试题解析(07)-多线程编程与线程同步

Java多线程系列——线程池简介

如何使用 IE/.Net/C# 进行真正的多线程 Web 挖掘?

多线程async&await

JAVA多线程与多进程