I have an MDB which uses container managed transaction (my container is IBM Websphere 7).
Websphere is using a global (JTA) transaction.
If my MDB thread starts a worker thread, and that thread begins a transaction, will that new thread be within the same transaction as the MDB?
I want the MDB thread to commit its transaction and acknowledge the MQ message as soon as my worker thread is successfully started. I do not want my MDB to rollback if the worker thread rolls back.
Edit: The code in the thread has this - it is not using annotations:
txn = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
txn.begin();
So if look at txn.getStatus() it will be something other than STATUS_NO_TRANSACTION. Therefore I need to get the transaction manager appropriate for Websphere 7 and call "suspend()" before the txn.begin()? Is the correct approach to prevent problems?
Put the code which should not be in the same transaction as the onMessage() method into a separate method and set the transaction attribute for that method to REQUIRES_NEW. This will create a new transaction when the method is called and the success or failure of this new transaction won't affect the preexisting one.
By the way, you aren't supposed to do explicit thread management in JavaEE applications.
From the EJB 3.0 spec:
The enterprise bean must not attempt to manage threads. The enterprise
bean must not attempt to start, stop, suspend, or resume a thread, or
to change a thread’s priority or name. The enterprise bean must not
attempt to manage thread groups.
You could look at using the timer service to effectively create a separate thread while leaving thread management to the server.
If you are using ejb 3.1 an option would be to do the worker work in a method annotated with
#Asynchronous
This will give you a new transaction and the work will be performed in a separate thread.
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/asyncMethodOfEJB/AsyncMethodEJB.html
Read more about default transaction mode: Default EJB transaction mode for asynchronous methods?
Related
I have a main class that reads records from DB and passes to a spring gateway(Spring integration), from there on I split the messages into a multithreaded application with queues.
My Sping application is closing the context while the messages are still being processed by spring integration adapters.
Need a mechanism to only close the context after all of the messages get processed.
As a temporary workaround, I am using thread.sleep in a while loop to keep the program alive
Well, I would suggest to have a bean like:
Semaphore queueSemaphore = new Semaphore(1);
And acquire() it in the beginning of your application. Do the same in the end before closing application context. In this case the second acquire() will wait until release() somewhere in your application when you realize that all the messages have been just processed.
Another trick is via standard System.exit(0) in the point you see that all the messages are processed. But in this case you should not close application context manually.
I have a spring controller. The request thread from the controller is passed to the #Service annotated Service class. Now I want to do some background work and the request thread must some how trigger the background thread and continue with it's own work and should not wait for the background thread to complete.
My first question : is this safe to do this.?
Second question : how to do this.?
Is this safe
Not really. If you have many concurrent users, you'll spawn a thread for everyone of them, and the high number of threads could bring your server to its knees. The app server uses a pool of threads, precisely to avoid this problem.
How to do this
I would do this by using the asynchronous capabilities of Spring. Call a service method annotated with #Async, and the service method will be executed by another thread, from a configurable pool.
we are facing an issue with initializing our cache at server startup or application deployment. Initializing the cache involves
Querying a database to get the list of items
Making an rmi call for each item
Listening to the data on a JMS queue/topic
Constructing the cache
This initialization process is in startup code. All this is taking lot of time due to which the deployment is taking lot of time or server start time is increasing.
So what I proposed is to create a thread in the startup and run the initialization code in it. I wrote a sample application to demonstrate it.
It involves a ServletContextListener, a filter. In the listener I am creating a new thread in which the HeavyProcess will run. When it finishes an event will be fired which the filter will be listening. On receiving the event the filter will allow incoming http requests. Until then the filter redirects all clients to a default page which shows a message that the application is initializing.
I presented this approach and few concerns were raised.
We should not ideally create a thread because handling the thread will be difficult.
My question is why cant we create a thread like these in web applications.
If this is not good, then what is the best approach?
If you can use managed threads, avoid unmanaged ones. The container has no control over unmanaged threads, and unmanaged threads survive redeployments, if you do not terminate these properly. So you have to register unmanaged threads, and terminate these somehow (which is not easy as well, because you have to handle race-conditions carefully).
So one solution is to use #Startup, and something like this:
#Schedule(second = "*/45", minute = "*", hour = "*")
protected void asyncInit(final Timer timer) {
timer.cancel();
// Do init here
// Set flag that init has been completed
}
I have learned about this method here: Executing task after deployment of Java EE application
So this gives you an async managed thread, and deployment will not be delayed by #PostConstruct. Note the timer.cancel().
Looking at your actual problem: I suggest using a cache which supports "warm starts".
For example, Infinispan supports cache stores so that the cache content survives restarts. If you have a cluster, there are distributed or replicated caching modes as well.
JBoss 7 embeds Infinispan (it's an integrated service in the same JVM), but it can be operated independently as well.
Another candidate is Redis (and any other key/value store with persistence will do as well).
In general, creating unmanaged threads in a Java EE environment is a bad idea. You will loose container managed transactions, user context and many more Java EE concepts within your unmanaged thread. Additionally unmanaged threads may block the conainer on shutdown if your thread handling isn't appropriate.
Which Java EE Version are you using? Perhaps you can use Servlet 3.0's async feature?
Or call a asynchronous EJB for doing the heavy stuff at startup (#PostConstruct). The call will then set a flag when its job is done.
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.
I'm using multithreaded wcf maxConcurrentCalls = 10. By logging calls to my service I see that 10 different threads are executing in my service class and that they are reused in the following calls.
Can I tell WCF to destroy/delete a thread so it will create a new one on the next call?
This is because I have thread-static state that I sometimes want to be cleared (on unexpected exceptions). I am using the thread-static scope to gain performance.
WCF doesn't create new threads. It uses threads from a thread pool to service requests. So when a request begins it draws a thread from this pool to execute the request and after it finishes it returns the thread to the pool. The way that WCF uses threads underneath is an implementation detail that you should not rely on. You should never use Thread Static in ASP.NET/WCF to store state.
In ASP.NET you should use HttpContext.Items and in WCF OperationContext to store some state that would be available through the entire request.
Here's a good blog post you may take a look at which illustrates a nice way to abstract this.