In various session management schemes, Threadlocal mode has been used in a large number of applications. Threadlocal is a more special thread binding mechanism in Java. Through ThreadLocal, it is always related to the current thread, that is, JVM is a private local instance access space, which provides a concurrent access problem that often occurs for multithreaded environments. An isolation mechanism. First, we need to know that sessionFactory is responsible for creating session, SessionFactory is a thread secure, multiple concurrent threads can access a sessionFactory at the same time and get a session instance from it. SESSION is not a thread security, that is, if multiple threads perform data access at the same time, it will cause session data access logic confusion. Here is a typical Servlet, we are trying to achieve Session session reuse by a class variable to avoid each operation must re-create: public class TestServlet extends HttpServlet {private Session session; public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {session = getsession (); dosomething (); session.flush ();} public void dosomething ()} public void dosomething () {... // Based on the session-based access operation}} code looks correct, even There may not happen when we test, but such a generation of Hibernate Developer's Guide Version 1.0september 2, 2004 SO MANY OPEN SOURCE PROJECTS. Why not open your documents? Code is compiled into the actual operational environment, The inexplicable mistakes are likely to make us not find the mind. where is the problem? First, the servlet runs multithreaded, and the application server does not create a servlet instance for each thread, that is, TestServlet has only one instance in the application server (which in Tomcat, other application servers may have Different implementation), and this example will be used in combination with many threads, and the doget method will also be repeatedly called by different threads. It is conceivable that each calling doget method, this unique TestServlet instance session variable will be reset During the operation of thread a, other threads are also executed, then the SESSION reference will change, then the thread A is called again, and the session that may be used at this time is no longer consistent, obviously, error It is not until. Threadlocal's emergence makes this problem to solve.
Our above example some minor modifications: public class TestServlet extends HttpServlet {private ThreadLocal localSession = new ThreadLocal (); public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {localSession.set (getSession ()) Dosomething (); session.flush ();} public void dosomething () {session session = (session) localsession.get (); ... // Based on the session access operation}} can be seen, LocalSession is an object of a Threadlocal type. In the Doget method, we save the acquired session instance through its SET method, and remove the Session instance through the GET method. This is the uniqueness of Threadlocal, which maintains a private variable space for each thread. In fact, the principle is the principle to maintain a map in JVM. This MAP's key is the current thread object, and Value is an object instance saved by thread through the ThreadLocal.SET method. When the threadlocal.get method is called, Threadlocal removes the corresponding object returns in the MAP according to the reference to the current thread object. Thus, ThreadLocal is separated by different threads by reference to the reference of each thread object, thereby isolating the variables of different threads. In the example of the Hibernate official development manual, a good role model through Threadlocal maintenance session:
public class HibernateUtil {private static SessionFactory sessionFactory; static {try {// Create the SessionFactorysessionFactory = newConfiguration () configure () buildSessionFactory ();} catch (HibernateException ex) {throw new RuntimeException ( "Configuration problem:".. ex. getMessage (), ex);}} public static final ThreadLocal session = new ThreadLocal (); public static Session currentSession () throws HibernateException {Session s = (Session) session.get (); // Open a new Session, if this Thread Has None Yetif (S == Null) {s = sessionFactory.opensesis (); session.set (s);} returnit s;} public static void closesession () throws hibernateException {session s = (session) session.get ( ); session.set (null); if (s! = null) s.close ();}} In the code, as long as you get the session instance with the above tool class, we can achieve the session shares within the range of threads. Avoid frequently created and destroying the Session instance in the thread. However, pay attention to the session at the end of the thread. At the same time, it is worth mentioning that the new version of Hibernate has built a latency load mechanism when handling Session, only when the database operation is really generated, will obtain database connections from the database connection pool, we don't have to worry too much about the session The database connection is continuously occupied in the entire thread lifecycle.
For web programs, we can easily implement Session Management within the thread lifecycle with the newly introduced Filter mechanism in the Servlet 2.3 specification (for details on the specific description of the Filter, please refer to the servlet2.3 specification). The Filter's life cycle runs through the servlet covered (JSP can also be seen as a special servlet) and its underlying object. Filter is executed before the servlet is called, and ends after the servlet call. Therefore, managing session in FILTER is designed for WEB programs. The following is managed by a Session Filter for typical cases: public class PersistenceFilter implements Filter {protected static ThreadLocal hibernateHolder = new ThreadLocal (); public void doFilter (ServletRequest request, ServletResponseresponse, FilterChain chain) throws IOException, ServletException {hibernateHolder.set (getSession ()); Try {... chain.dofilter (request, response); ...} finally {session sess = (session) hibernateHolder.get (); if (sess! = null) { HibernateHolder.set (NULL); try {sess.close ();} catch (hibernateException ex) {throw new servletexception (ex);}}}} ... Hibernate Developer's Guide Version 1.0september 2, 2004 So Many Open Source Projects? Why NOT OPEN YOUR Documents?} Perform the session instance by getting and closing the session in the Dofilter, and all objects run during the cycle (the remaining Filter in the FILTER chain Reuse, ensuring that only one session in an HTTP Request process is taken, and the overall performance performance is improved. In actual design, the SESSION is reused to be threaded, which is generally sufficient, attempting to achieve user-level session reuse through httpsession can cause other problems. Everything can't be fire, the session reuse is also the same. Author Blog:
http://blog.9cbs.net/jhxck/