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.