使用 DbContext.Database.Connection.CreateCommand 的并发问题

发布于 2024-11-04 10:38:55 字数 844 浏览 0 评论 0原文

我将尝试解释这一点,但不会真正破坏我正在开发的应用程序的整个设计。因为谁在乎这个呢。如果相关的话,我可以提供更多细节,但我想我涵盖了下面的所有内容。

主要问题

我有一些需要定期执行的存储过程。我从数据库表中获取过程名称,因此我的应用程序没有关于它们的硬编码知识。这是设计使然。我目前正在使用实体框架来进行所有数据访问。

我的应用程序是多线程的——我获取需要运行的所有进程,然后迭代每个进程,从我的配置表中获取其属性,并将其排队以在应用程序线程池中的单独线程上运行。

我正在使用 Database.Connection.CreateCommand 方法并执行过程——将数据拉入数据表。当我只执行一个过程时,这种方法效果很好,但当

问题是我遇到并发问题时。我得到的具体异常是

System.Data.SqlClient.SqlException: 不允许新交易,因为 还有其他线程在运行 会议。

我假设这是因为我试图执行我的过程,同时还通过实体框架访问另一个过程的属性。


我想到的潜在解决方案/思路

  • 如果我编写一个具有我需要的字段的模型类,我可以使用 DbContext.Database.SqlQuery 方法让它正常工作。但是如果我根本不想编写模型类怎么办?有没有办法可以做到这一点并让实体框架实际处理查询?

  • 在开始执行任何过程之前,我可以获取所有属性。那可能会很好用。如果我将属性定义为模型上的 ICollections,告诉我要运行什么过程,有没有办法在我从数据库中选择所述模型时强制它们加载,而不是在稍后迭代它们来读取它们时加载?

I'm gonna try to explain this without actually mucking through the whole design of the application I'm working on. Cause who cares about that. If it's pertinent, I can give more detail but I think I cover everything below.

main problem:

I've got a few stored procedures that I need to execute periodically. I get the proc names from a database table, so my application has no hard coded knowledge of them. This is by design. I'm currently using the entity framework to do all my data access.

My application is multi threaded -- I grab all the procs that I need to run, then iterate through each one, grab its properties from my configuration tables and queue it up to run on a separate thread in the app's thread pool.

I'm using the Database.Connection.CreateCommand method and executing the procs -- pulling the data into a data table. This works out well when I'm only executing one proc, but when

Problem is that I run into concurrency issues. The specific exception I'm getting is

System.Data.SqlClient.SqlException:
New transaction is not allowed because
there are other threads running in the
session.

I'm assuming this is because I'm trying to execute my procedure while also accessing the properties of another procedure via the entity framework.


Potential solutions / trains of thought that occur to me:

  • I can get this to work just fine using the DbContext.Database.SqlQuery method if I write a model class that has the fields I need. But what if I don't want to write a model class at all? Is there a way I can do this and let the entity framework actually handle the query?

  • I could grab all of the properties before i start executing any procs. That would probably work fine. If I define my properties as ICollections on the model that tells me what procedure to run, is there a way to force them to load when I select said model from the DB instead of when I iterate through them later to read them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初心未许 2024-11-11 10:38:55

这里的主要问题是您正在通过多个线程使用单个数据库连接(Database.Connection 为所有 CreateCommand 调用返回相同的实例),并且您试图定义多个交易同时进行。这种情况的解决方案只有一个 - 每个存储过程/线程使用一个新连接。您应该能够通过调用Database.Connection.ConnectionString 来获取连接字符串。

  • 除非您在每个线程中运行新的上下文,否则您的第一个解决方案将无法解决问题。
  • Database.SqlQuery 始终需要类型来加载数据。实体框架通过将结果集映射到类型来简化数据访问。如果您没有类型,则无法利用 EF 的任何优势。
  • 立即加载关系的方式称为急切加载,由查询中使用的 Include 方法执行。您只需说出必须立即加载映射实体上的哪些导航属性。

The main problem here is that you are using single database connection (Database.Connection returns the same instance for all your CreateCommand calls) by multiple threads and you are trying to define multiple transactions concurrently. The solution for this scenario is only one - use a new connection per stored procedure / thread. You should be able to get connection string by calling Database.Connection.ConnectionString.

  • Your first solution will not solve the problem unless you run a new context in each thread.
  • Database.SqlQuery always require type for loading data. Entity framework make easier data access by mapping result sets to types. If you don't have a type you can't take any advantage of EF.
  • The way to load relation immediately is called eager loading and is performed by Include method used in the query. You will just say which navigation properties on the mapped entity must be loaded immediately.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文