Reputation: 1287
I have a NHibernate repository class, which is doing some READ operations on multiple table in a single transaction.
But I have an old piece of code which is trying to call this NHibernate class on Parallel Threads, something like
someList.AsParallel().Select(x=>x.repo.GetData());
And the operation fails saying SQL Doesn't support multiple transactions , How can make the ISession in NHibernate thread safe?
Upvotes: 0
Views: 707
Reputation: 9864
NHibernate ISession
is not thread safe, period.
From NHibernate reference documentation Chapter 1, Getting started section:
An
ISession
is a non-threadsafe object that represents a single unit-of-work with the database.
You should change your old piece of code instead.
This piece of code looks like a coding horror anyway. It suffers the n+1 loads bad practice. Usually this one occurs with lazy-loading not correctly setup (by forgetting to set adequate batch-size
in mappings on entities and collections, while not having set default_batch_fetch_size
configuration parameter). But there, it is explicitly coded!
Calling DB in a loop is a performance anti-pattern that you should fix first. Calling it in an AsParallel
looks only as a poor attempt from original developer to "optimize" this coding horror.
To fix it, you should load all your data in a single call, then dispatch it on your list as needed. You may first project your data into a dictionary for avoiding an O(n²) dispatching algorithm.
Once done, the AsParallel
should have vanished, and your thread safety trouble too.
If the thing is too complex (way more that what your example shows), or really corresponds to something that needs to be done with parallelism, then you should instantiate one dedicated ISession
for each GetData
in your parallel processing.
Upvotes: 4
Reputation: 64628
Note that when using lazy loading and proxies, not even the entities are thread safe!
Upvotes: 1