Do NHibernate sessions per thread work with threadpool? - nhibernate

If I somehow manage to configure NHibernate sessions to be per thread, will that work when I process data in threads coming from a thread pool?
Threads from the pool are "recycled" (yes?) so if a thread was already used once and it gets called into action again, will its session be no loner useable?

The correct handling of the ISession is fully in your hands, you are responsible. Not the ThreadPool. So, if you use session instance per thread, you still should know (and manage) when it is created, and that it is explicitly closed and disposed.
If that ISession management is in place, do not worry about issues with a Thread pool. On the other hand, it also means, that opening and keeping a session in [ThreadStatic] field - is not correct:
Will values in my ThreadStatic variables still be there when cycled via ThreadPool?
short extract:
The thread pool (by design) keeps the threads alive between calls.
This means that the ThreadStatic variables will persist between calls
to QueueUserWorkItem.

Related

Why A single Jedis instance is not threadsafe?

https://github.com/xetorthio/jedis/wiki/Getting-started
using Jedis in a multithreaded environment
You shouldn't use the same instance from different threads because you'll have strange errors. And sometimes creating lots of Jedis instances is not good enough because it means lots of sockets and connections, which leads to strange errors as well.
A single Jedis instance is not threadsafe
! To avoid these problems, you should use JedisPool, which is a threadsafe pool of network connections. You can use the pool to reliably create several Jedis instances, given you return the Jedis instance to the pool when done. This way you can overcome those strange errors and achieve great performance.
=================================================
I want to know why? Can anyone help me please
A single Jedis instance is not threadsafe because it was implemented this way. That's the decision that the author of the library made.
You can check in the source code of BinaryJedis which is a super type of Jedis https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/BinaryJedis.java
For example these lines:
public Transaction multi() {
client.multi();
client.getOne(); // expected OK
transaction = new Transaction(client);
return transaction;
}
As you can see the transaction field is shared for all threads using Jedis instance and initialized in this method. Later this transaction can be used in other methods. Imagine two threads perform transactional operations at the same time. The result may be that a transaction created by one thread is unintentionally accessed by another thread. The transaction field in this case is shared state access to which is not synchronized. This makes Jedis non-threadsafe.
The reason why the author decided to make Jedis non-threadsafe and JedisPool threadsafe might be to provide flexibility for clients so that if you have a single-threaded environment you can use Jedis and get better performance or if you have a multithreaded environment you can use JedisPool and get thread safety.

DMLC and concurrent consumers working

Does DMLC creates separate threads for each concurrent consumer? What happens under the hood? The documentation writes this:
Actual MessageListener execution happens in asynchronous work units which are created through Spring's TaskExecutor abstraction. By default, the specified number of invoker tasks will be created on startup, according to the "concurrentConsumers" setting.
I am not able to understand this, are these tasks executed in parallel? If yes, what are the default limits for this, like thread count etc.?
Thanks!
Yes a separate thread is used for each consumer (obtained from the task executor). By default, a SimpleAsyncTaskExecutor is used and the thread is destroyed when the consumer is stopped. There is no thread limit beyond the container's concurrency settings.
If you inject a different kind of task executor (such as a ThreadPoolTaskExecutor) you must make sure it has enough available threads to support your container's concurrency settings. Container threads are generally long-lived.

Is it possible to dictate use of RPC callback threads?

I am working on a bug that related to an unmanaged MTA COM object. The object has Lock and Unlock methods and uses a mutex that requires the same thread that called Lock to call Unlock.
The problem is that when Lock and Unlock are called from a managed STA thread (using COM interop), the calls come into the COM object on a RPC callback thread but the callback thread that is used is not always the same for both calls. When it is not the same, the Unlock call fails because it can't unlock the mutex.
In other words:
Managed STA thread 1 -> RPC callback (thread 11) -> Lock
Managed STA thread 1 -> RPC callback (thread 12) -> Unlock -> Error
I am trying to evaluate all possible solutions before making any decisions on a fix. As such, I am trying to find out:
1) Is there is a way to prevent a RPC callback thread from being used in the first place? In my testing, if I make the calls to the object from an unmanaged STA thread, the calls seem to come in on the calling thread itself. What is different when the call is coming from .Net that necessitates the use of an RPC callback thread? Is there any way to prevent RPC callbacks from being used? (except for using an MTA calling thread)
2) If not, is there a way to force a consistent RPC callback thread to be used from the same managed STA thread?
This is by design for a free-threaded server. COM takes your word for it and allows stubs to use arbitrary RPC threads. You cannot make any assumptions about the thread identity, the RPC thread is picked from a pool and is recycled. Unfortunately it often picks the same one when the calls are sequenced so it will look like it works fine at first. But trouble starts as soon as more than one concurrent server call is made. There is no option to make it selective, a free-threaded server promises to not care. Nor could that work well in practice, it would either scale horribly or induce deadlock.
You therefore cannot use a mutex to implement locking, it has thread affinity. A semaphore is a good choice.

ISessionFactory.OpenSession() from multiple threads

I would like to know the behavior of the following.
basically i have a static ISessionFactory, and an application with 10 threads running and each of them would use ISessionFactory.OpenSession() to get an ISession. Would this cause any problem?
No. This is correct. You want to make sure you have a separate session for each thread.
SessionFactory is thread safe but not Session. So if you open a session with ISessionFactory.OpenSession() in a thread and use it there(within that thread) without sharing with other thread, you are safe to go.
But do not use ISessionFactory.GetCurrentSession() among multiple therads.
This will not cause any problems, but make sure that:
you don't 'leak' ISession instance (no other threads will ever have access to it)
you properly Dispose session when you no longer need it
ISessionFactory on the other hand is thread safe and can be used from multiple threads without additional synchronization on your part.
using(ISession session = _sessionFactory.OpenSession()) {
// use session making sure it will not become visible to other threads
}

How long can/should an NHibernate session be kept open?

I've created a windows service which is listening to a MSMQ. For each message I receive, some DB transactions need to be made. Later it might be possible that there will be 1 message every second.
Currently the Nhib session is kept open until the service is stopped manually.
Is it a good practice or should I close the session after each message?
Thanks in advance
An NHibernate session is meant to be relatively short lived, so its generally not a good idea to keep it active for a longer period. The session caches entities and as more entities are fetched more data is cached, if you don't manage the caching in some way. This leads to a performance degradation.
The NHibernate docs describe ISession like this:
A single-threaded, short-lived object representing a conversation between the application and the persistent store. Wraps an ADO.NET connection. Factory for ITransaction. Holds a mandatory (first-level) cache of persistent objects, used when navigating the object graph or looking up objects by identifier.
I would suggest using a session-per-conversation, i.e. if you have a few db operations that "belong together" you use the same session for those operations, but when those operations are done you close the session.
So, using a new session for each message you process sounds like a good idea.
In contrast to the session factory (ISessionFactory) which is thread safe you should open and close the session (ISession) with every database transaction.