Spring + Hibernate session management across multiple threads - multithreading

I am building a system, where each request from a client side spawns multiple threads on server side. Each thread then is using one or more DAOs (some DAOs can be used by more than one thread at the time). All DAOs are injected (#Autowired) to my thread classes by Spring. Each DAO receives SessionFactory injected as well.
What would be proper way of managing Hibernate sessions across these multiple DAOs so I would not run into problems because of multithreaded environment (e.g. few DAOs from different threads are trying to use the same session at the same time)?
Would be enough that I specify hibernate.current_session_context_class=thread in Hibernate configuration and then everytime in DAO simply use SessionFactory.getCurrentSession() to do the work? Would it properly detect and create sessions per thread as needed?

Yes. It is enough.
When setting hibernate.current_session_context_class to thread , the session returned from SessionFactory.getCurrentSession() is from the ThreadLocal instance.
Every thread will have their own, independently ThreadLocal instance, so different threads will not access to the same hibernate session.
The behaviour of SessionFactory.getCurrentSession() is that: if it is called for the first time in the current thread, a new Session is opened and returned. If it is called again in the same thread, the same session will be returned.
As a result , you can get the same session to use in different DAO methods in the same transaction code by simply calling SessionFactory.getCurrentSession(). It prevents you from passing the Hibernate session through the DAO method 's input parameters in the case that you have to call many different DAO methods in the same transaction code.

Related

Is ASP.NET Core Session implementation thread safe?

I know that there is an analogous question but that is about ASP.NET and not about ASP.NET Core. The answers are 7-9 years old, and mixing there talking about ASP.NET and ASP.NET Core may not be a good idea.
What I mean thread safe in this case:
Is it safe to use the read write methods (like Set(...)) of the Session (accessed via HttpContext, which accessed via an injected IHttpContextAccessor) in multiple requests belonging to the same session?
The obvious answer would be yes, because if it would not be safe, then all developers should make their session accessing code thread safe...
I took a look of the DistributedSession source code which seems to be the default (my session in the debugger which accessed as described above is an instance of DistributedSession) and no traces of any serialization or other techniques, like locks... even the private _store member is a pure Dictionary...
How could be this thread safe for concurrent modification usage? What am I missing?
DistributedSession is created by DistributedSessionStore which is registered as a transient dependency. That means that the DistributedSessionStore itself is implicitly safe because it isn’t actually shared between requests.
The session uses a dictionary as the underlying data source which is also local to the DistributedSession object. When the session is initialized, the session initializes the _store dictionary lazily when the session is being accessed, by deserializing the stored data from the cache. That looks like this:
var data = _cache.Get(_sessionKey);
if (data != null)
{
Deserialize(new MemoryStream(data));
}
So the access to _cache here is a single operation. The same applies when writing to the cache.
As for IDistributedCache implementations, you can usually expect them to be thread-safe to allow parallel access. The MemoryCache for example uses a concurrent collection as the backing store.
What all this means for concurrent requests is basically that you should not expect one request to directly impact the session of the other request. Sessions are usually only deserialized once so updates that happen during the request (by other requests) will not appear.

web app, jsp, and multithreaded

I'm currently building a new web app, in Java EE with Apache Tomcat as a webserver.
I'm using jsps and servlets in my work.
my question is:
I have a very standard business logic. None of it is synchronized, will only a single thread of my web app logic will run at any given time?
Since making all functions "synchronized" will cause a huge overhead, is there any alternative for it?
If i have a static method in my project. that makes a very simple thing, such as:
for (int i=0;i<10000;i++ ) {
counter++;
}
If the method is not thread safe, what is the behavior of such method in a multi user app? Is it unexpected behavior?!
and again in a simple manner:
if i mean to build a multi user web app, should i "synchronize" everything in my project? if not all , than what should i sync?
will only a single thread of my web app logic will run at any given time?
No, the servlet container will create only one instance of each servlet and call that servlet's doService() method from multiple threads. In Tomcat by default you can expect up to 200 threads calling your servlet at the same time.
If the servlet was single-thread, your application would be slow like hell, see SingleThreadModel - deprecated for a reason.
making all function "synchronized" will make a huge overhead, is there any alternative for it?
There is - your code should be thread safe or better - stateless. Note that if your servlet does not have any state (like mutable fields - unusual), it can be safely accessed by multiple threads. The same applies to virtually all objects.
In your sample code with a for loop - this code is thread safe if counter is a local variable. It is unsafe if it is a field. Each thread has a local copy of the local variables while all threads accessing the same object access the same fields concurrently (and need synchronization).
what should i sync?
Mutable, global, shared state. E.g. In your sample code if counter is a field and is modified from multiple threads, incrementing it must be synchronized (consider AtomicInteger).

EJBs - Architectural issue

I'm currently writing a new EJB application which basically is supposed to receive messages from a web service and launch a downloading process based on this message content. This application will run on Glassfish 3.1.1.
My first idea was to create a singleton bean that would read the messages from the web service and use a stateful session bean to initiate and handle the download itself. I need to use stateful beans because I need to have a convertational state between my singleton and stateful bean (download status, etc.)
The "problem" is if I receive several messages from the web service I'm supposed to start several downloads in parallel, each download with its own context of course. How am I supposed to achieve this as if I invoke a stateful session bean from my singleton I'll always get the same bean, correct? The only solution I see is to use threads that would be created and launched from my singleton but this is not permitted by EJB specification...
Thanks for your help !
I don't think you want a stateful session bean here. The point of a stateful bean is that that maintains state in the scope of a session, which is a relationship with a particular client. In your case, there isn't one download per client (are there even any clients?), which means that this is not an appropriate scope.
If you just want multiple threads, use a stateless bean with an #Asynchronous method. You would probably have to handle status updates using a callback to the singleton.
Why do you need a singleton bean here? Is just stateful session bean is not good enough? You want simultaneous downloads, you want statefulness, so why to use singleton? Can you explain a little bit more?

EJB pooling vs Spring: how to manage work load in spring?

When an EJB application receives several requests (work load) it can manage this work load just POOLING the EJBs, so when each EJB object is being used by a thread, the next threads will have to wait queued until some EJB ends up the work (avoiding overloading and efficiency degradation of the system).
Spring is using stateless singletons (not pooling at all) that are used by an "out of control" number of threads.
Is there a way to do something to control the way the work load is going to be delivered? (equivalent to the EJB instance pooling).
Thank you!
In the case of the web app, the servlet container has a pool of threads that determine how many incoming HTTP requests it can handle simultaneously. In the case of the message driven POJO the JMS configuration defines a similar thread pool handing incoming JMS messages. Each of these threads would then access the Spring beans.
Googling around for RMI threading it looks like there is no way to configure thread pooling for RMI. Each RMI client is allocated a thread. In this case you could use Spring's Task Executor framework to do the pooling. Using <task:executor id="executor" pool-size="10"/> in your context config will set up a executor with 10 threads. Then annotate the methods of your Spring bean that will be handling the work with #Async.
Using the Spring task executor you could leave the Servlet and JMS pool configuration alone and configure the pool for your specific work in one place.
To achieve a behaviour similar to the EJB pooling, you could define your own custom scope. Have a look at SimpleThreadScope and the example referenced from this class' javadoc.
The difference between Spring and EJB is, that Spring allows multiple threads on an single instance of an bean, while in EJB you have only one tread per bean (at one point in time).
So you do not need any pooling in Spring for this topic. But on the other hand you need take care that you implement your beans in a threadsave way.
From the comments:
Yes I need it if I want to limit the number of threads that can use my beans simultaneously
One (maybe not the best) way to handle this is to implement the application in normal spring style (no limits). And than have a "front-controller" that accept the client request. But instead of invoking the service directly, it invokes the service asyncron (#Async). May you use some kind of async proxy instead of making the service itselfe asyncron.
class Controller{...
Object doStuff() {return asyncProxy.doStuffAsync().get();}
}
class AsyncProxy{...
#Async Future<Object> duStuffAscny{return service.doStuff();
}
class Service{...
Object doStuff{return new Object();}
}
Then you only need to enable springs Async Support, and there you can configure the Pool used for the Threads.
In this case I would use some kind of front controller, that starts an new Async

Hibernate session in threads

Im having some problem with a service that acts as a listener of some events that are originated from an external library, that library creates a thread for reading comm port and send back the data to my listener (the grails service) on certain cases.
The problem is that i cannot update the database when methods are called from the reading thread becose grails bound the hibernate session to threads.
There is any chance to get the hibernate session for that thread??
There is a configuration parameter to propagate or inject the session to threads??
i have seen the background thread plugin but it seems that is only useful if the thread is created by grails.
I think you are not getting a session because your service is not being invoked as part of a standard http request.
Grails has some convenience methods like
withSession
withNewSession
withTransaction
that might fit the bill

Resources