.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 更好地支持多线程?的主要内容,如果未能解决你的问题,请参考以下文章