简体   繁体   English

NHibernate会话可以在不同的线程中打开两个数据读取器吗?

[英]Can an NHibernate session have two data readers open in separate threads?

I'd like to know the correct approach for running two simultaneous queries using NHibernate. 我想知道使用NHibernate运行两个同时查询的正确方法。 Right now, I have a single ISession object that I use for all my queries: 现在,我有一个ISession对象,我用于所有查询:

session = sessionFactory.OpenSession();

In one thread, I'm loading some data which takes 10-15 seconds, but I don't need it right away so I don't want to block the entire program while it's loading: 在一个线程中,我正在加载一些需要10-15秒的数据,但是我不需要它,所以我不想在加载时阻止整个程序:

IDbCommand cmd = session.Connection.CreateCommand();
cmd.CommandType = CommandType.TableDirect;
cmd.CommandText = "RecipesForModelingGraph";
IDataReader reader = cmd.ExecuteReader();

while (reader.Read())
{
   // Do stuff
}

reader.Close();

This works fine, however in another thread I might be running a query such as: 这工作正常,但在另一个线程中,我可能正在运行查询,例如:

var newBlah = new Blah();
session.Save(newBlah);

When the above transaction commits, I occasionally get an exception: 当上述事务提交时,我偶尔会遇到异常:

Additional information: There is already an open DataReader associated with this Command which must be closed first. 附加信息:已经有一个与此命令关联的打开DataReader,必须先关闭它。

Now, I thought maybe this was because I was running everything in the same transaction. 现在,我想也许这是因为我在同一个交易中运行了所有内容。 So, I surrounded all my loading code with: 所以,我用我的所有加载代码包围:

using (ITransaction transaction = session.BeginTransaction(IsolationLevel.Serializable))
{
   // Same DataReader code as above
}

However, the problem has not gone away. 然而,问题并没有消失。 I'm thinking maybe I need each thread to have its own ISession object. 我想也许我需要每个线程都有自己的ISession对象。 Is this the correct approach, or am I doing something wrong. 这是正确的方法,还是我做错了什么。 Note, I only want a single open connection to the database. 注意,我只想要一个到数据库的单一开放连接。 Also, keep in mind the background thread is only loading data and nothing else, so I'm not worried about isolation levels and data changing as its being read. 另外,请记住后台线程只加载数据而不是其他内容,因此我不担心隔离级别和数据在读取时会发生变化。

The session is tied to the thread and the Commands created are linked to the sessions connection object. 会话与线程绑定,创建的命令链接到会话连接对象。 So yes, if a commit or close is executed while an open reader exists you will get an exception. 所以,是的,如果在打开的阅读器存在时执行提交或关闭,您将获得异常。

You could Join() your threads and wait until all are complete before closing/committing. 您可以加入()您的线程并等待所有完成后再关闭/提交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM