I was writing j2ee code but i am facing a problem with session attribute.
Regarding ensuring of thread safety for session attributes which is being set and accessed in a servlet?
As, i know we can not implement "SingleThreadModel" because this is deprecated in java and also we can not synchronize the doXXXX() method.
I tried to use "SingleThreadModel" but it did not work.
Then How can i ensure it?
Can i synchronize the session object for the same?
please tell me, how to fix it.
You need a session scoped mutex. I.e. synchronize on the session, or better a use case specific object in the session.
You should keep the scope of the mutex as small as possible, as you might result in serializing your requests. I tried it once on a project of mine, where I used Spring's RequestMappingHandlerAdapter.setSynchronizeOnSession() which simply synchronizes on the session for each request. This had a significant impact on a page which displays a list of rendered images. I could watch appearing those images sequentially.
Related
Okay. What I want to do is be able to, when I update a user, invalidate any session that they currently have in order to force a refresh of credentials. I don't care about being able to directly access the session-specific user data. Ideally, I would also be able to restrict users to one session by a similar manner.
What I tried doing is creating a HashMap using the username as key and HttpSession as the value (my actual setup is a little more involved, but after repeated seemingly inexplicable failures, I boiled it down to this simple test). However, whenever I attempt to tell the retrieved HttpSession to invalidate, it seems to be invalidating the current [admin] session. Is HttpSession inextricably bound to the current request?
Or is there an entirely different way to deal with this?
If it happens to matter, I'm using Jetty 6.1.26.
There's no straight forward way. The easiest way I can think of is to keep a flag on the database (or a cahche) and check it's validity on each request.
Or you can implement a HTTP Session listener and keep a HashMap of user sessions that can be accessed and invalidated.
I haven't tried any of these out so I don't know of any performance issues. But it should be acceptable for most applications.
Well, as far as I can tell, there's no way around it. Using a request-scoped bean didn't work as I expected (although it did give me good insights into how Spring operates, intercepting field accesses). I ended up using a dirty flag on my SessionHandler (a session-scoped bean) with a very high-priority aspect checking and, if necessary, calling invalidate() on the session in the user's next request. I still ended up having all my SessionHandlers register with a SessionManager, and a #PreDestroy method to unregister them in order to avoid a bunch of null entries in the map.
I have a Jersey (version 2) resource that, during request handling, creates an object that is used throughout the request.
I would like to cache this object in a thread local storage so that other request handlers that use the same thread could re-use this object.
Is this possible? How is this done in Jersey? I am totally new to Jersey and to Java in general, please help. Can I use javax.ws.rs.container.ContainerRequestContext for this? How? How do I clear the cache?
EDIT:
Specific questions:
If I use javax.ws.rs.container.ContainerRequestContext to cache my objects, at what point can I clear the cache?
Is clearing the cache necessary at all in this case?
Is it a good practice to use thread storage as a cache in servlets?
It is advisable to avoid caching in REST as it is supposed to be stateless. But most simple solution could be to use HttpSession object to store your object and retrieve it later and then dispose it off.
For details you can refer this question:Link
ThreadLocal<Session> tl = new ThreadLocal<Session>();
tl.set(session);
to get the session,
Employee emp = (Employee)((Session)tl.get().get(Employee.class, 1));
If our application is web based, the web container creates a separate thread for each request.
If all these requests concurrently using the same single Session object , we should get
unwanted results in our database operations.
To overcome from above results, it is good practice to set our session to threadLocal object
which does not allows concurrent usage of session.I think, If it is correct the application performance should be very poor.
What is the good approach in above scenarios.
If I'm in wrong track , in which situations we need to go for ThreadLocal.
I'm new to hibernate, please excuse me if this type questioning is silly.
thanks in advance.
Putting the Hibernate Session in ThreadLocal is unlikely to achieve the isolation between requests that you want. Surely you create a new Session for each request using a SessionFactory backed by a connection pooling implementation of DataSource, which means that the local reference to the Session is on the stack anyway. Changing that local reference to a member variable only complicates the code, imho.
Anyhow, ensuring isolation within a single container doesn't address the actual problem - how is data accessed efficiently while maintaining consistency within a multi-threaded environment.
There are two parts to the problem you mention - the first is that a database connection is an expensive resource, the second that you need to ensure some level of data consistency between threads/requests.
The general approach to the resource problem is to use a database connection pool (which I'd guess you're already doing). As each request is processed, connections are obtained from the pool and returned when finished but importantly the connections in the pool are maintained beyond the lifetime of a request thus avoiding the cost of creating a connection each time it is needed.
The consistency problem is a little trickier and there's no one size fits all model. What you need to be doing is thinking about what level of consistency you need - questions like does it matter if data is read at the same time it's being written, do updates absolutely have to be atomic, etc.
Once you know the answer to these questions there two places you need to look at consistency - in the database and in the code.
With the database you need to look at database level locks and create a scheme suitable for your application by applying that appropriate isolation levels.
With the code, things are a little more complicated. Data is often loaded and displayed for a period of time before updates are written back - no problem if there's a single user but in a multi-user system it's possible that updates are made based on stale data or multiple updates occur simulatiously. It may be acceptable to have a policy of last update wins, in which case it's simple, but if not you'll need to be using version numbers or old/new comparisons to ensure integrity at the time the updates are applied.
I am not sure if you have compulsion of using ThreadLocal. Using ThreadLocal to store session object is definitely is not a good idea, specially when you are using hibernate along with spring.
A typical scheme for using Hibernate with Spring is:
Inject the sessionFactory in your DAO. I assume that you have sessionFactory already configured which is backed by a pooled datasource.
Now in your DAO class, a session can be accessed as follows.
Session session = sessionFactory.getCurrentSession();
Here is a link to related article.
Please note that this example is specific to Hiberante 3.x APIs. This takes care of session creation/closure/thread-safety aspect internally and its neat too.
I've recently taken on the database/hibernate side of our project and am having terrible trouble understanding some fundamentals of our design regarding the use of managed sessions.
We have a util class containing a static session that is only initialised once. Retrieval of the session is used by every DAO in the system via a static method getBoundSession(). The application runs 24/7. Is this a common design?
One of the benefits which is extremely useful, is that lazy attributes/collections on domain objects can be used throughout the business logic tier since the session is always open. Another benefit is that the objects retreived will stay cached within the session.
I feel we must be using Hibernate in the wrong way, it just doesn't seem right to have a single permanently open session. Also it causes problems when separate threads are using the util class, hence sharing the session. On the flip side I can't find a way to achieve the above benefits (particularly the first) with a different design. Can anyone shed any light on this?
Thanks
James
We have a util class containing a static session that is only initialised once. Retrieval of the session is used by every DAO in the system via a static method getBoundSession(). The application runs 24/7. Is this a common design?
Not it's not. The most common pattern in a multi-user client/server application is session-per-request and a session-per-application approach in a multi-user application is not only an anti-pattern, it's totally wrong:
A Session is not thread-safe.
You should rollback a transaction and close the Session after an Hibernate exception if you want to keep object state and database in sync.
The Session will grow indefinitely if keep it open too long.
You really need to read the whole Chapter 11. Transactions and Concurrency.
On the flip side I can't find a way to achieve the above benefits (particularly the first) with a different design.
Either use the OSIV (Open Session In View) pattern or load explicitely what you need per flow. And if you want to benefit from global caching, use the second level cache.
Keeping a session open for an extended period of time is OK (although that should not be eternity :-) A session should identify a unit of work - a coherent set of queries / updates which logically belong together. Can you identify such units in your app - e.g. client requests or conversations? If so, create a separate session for each of these.
You should also definitely use a separate session per thread (typically a unit of work is handled by a single thread anyway). A simple way to achieve this is using thread local storage.
It's an anti-pattern.
If you use one session for all requests. Then consider 100 clients (100 requests/threads) running almost simultaneously. You detach something from the session, but then another user reloads the same thing. You will need syncrhonization, which will hit performance. And you will have totally random behaviour that will be nightmare to debug.
The SessionFactory is static / per-application, not the Session. The factory should build a session whenever required. Read sessions and transactions docs at hibernate.
I trying to understand the best prastice of using ThreadLocal for the above questions. From my understanding the reason of using this is to ensure only one session/pm created for entire application. My question is
is there any impact of using threadlocal like this on clustering application? (example google app engine) ?
if u use "transactional" begin,commit on my application, i do not need to use threadlocal right? since "transaction" already ensure my session open and close properly?
if i need to use "transactional", tx, it should be in threadlocal as well?
why not just use "static" instead of "threadlocal" ?
i interested to hear feedback from you all regarding advantages/disadvantages of using this techinque?
Probably not unless your clustering software can migrate threads between nodes. In this case, you'd need to migrate the thread local data as well.
No. The transaction is attached to the session, so you must keep both in sync. While you can begin a transaction in thread A and commit it in thread B, it's usually very hard to make sure that this work reliably. Therefore: Don't.
Yes.
static is global for the whole application. threadlocal is global per Thread.
Conclusion: If you're a beginner in this area, I suggest to use Spring. The Spring Framework solves many of the problems for you and helps you with useful error messages when something breaks.
Follow the documentation to the letter, especially when it doesn't make sense. Chances are that you missed something important and the Spring guys are right.
ThreadLocal is not used to create one session for the whole application. It is used to create one session for every thread. Every user session will be one thread so the ThreadLocal ensures that every user accessing you web page/ database will get its own database connection. If you use a static singleton pattern every user on the server will use the same database connection and I don't know how that would work out.
The implementation of many of the Transaction engines is actually using ThreadLocal to associate the session state you have with the database to a particular thread. This makes for instance running multiple threads inside of a transaction very difficult.
ThreadLocal is a guarantee of Thread safety but queryable in a semi static way later on by another piece of code. Its a thread global variable. This makes it useful for temporary but session aware information. Another use beyond transactions might be holding onto internal parameters for Authorisation which are then checked with a proxy.