Resources:
Http://blog.sina.com.cn/s/blog_7ffb8dd5010146i3.html
http://lavasoft.blog.51cto.com/62575/51926/
First, the question of the proposed
we know that the session was created by Sessionfactory, while the implementation of Sessionfactory is thread-safe , and multiple concurrent threads can access a Sessionfactory and gets a session instance from it, and the session is not thread safe . The session contains state information related to database operations, so if multiple threads use a session instance for CRUD at the same time, it is likely to cause confusion in data access , and you can imagine that you simply cannot predict Do the sequential threads operate on one of your records?
Ii. Solution Ideas (using the threadlocal class collection )
As early as the launch of Java1.2, a new support was introduced in the Java platform: java.lang.ThreadLocal, which gives us a new choice when writing multithreaded programming. What is threadlocal? in fact, threadlocal is not a local implementation version of a thread, it is not a threads, but a thread local variable (threaded locals). Perhaps it would be more appropriate to name it Threadlocalvar. The thread local variable (ThreadLocal) function is very simple, that is, each thread that uses the variable provides a copy of the value of a variable, and each thread can independently change its own copy without conflicting with the other thread's copy . From a thread's point of view, it's as if every thread has exactly one of those variables.
threadlocal The class itself is not a variable to be accessed by the thread, and the member variable is the class. JDK1.5 adds a generic function to ThreadLocal, which is ThreadLocal, a generic t that is a local variable to thread. The thread accesses the variable t through Threadlocal's get and set methods.
How does threadlocal maintain a copy of a variable for each thread? In fact, the idea of implementation is simple, there is a map in the Threadlocal class that stores a copy of each thread's variable. For example, the following examples are implemented (for simplicity, no collection is considered for generics):
Public classThreadLocal {PrivateMap values = Collections.synchronizedmap (NewHashMap ()); PublicObject Get () {Thread CurrentThread=Thread.CurrentThread (); Object result=Values.get (CurrentThread); if(Result = =NULL&&!Values.containskey (CurrentThread)) {Result=InitialValue (); Values.put (CurrentThread, result); }returnresult; } Public voidset (Object newvalue) {values.put (Thread.CurrentThread (), newvalue); } PublicObject InitialValue () {return NULL; } }
Third, the solution steps
1. In the Hibernateutil class we need to define a static member variable to hold the session shared by the current thread.
Public classHibernateutil {Private StaticSessionfactory Factory; //to save a session in the current business thread using the Threadlocal collection Private StaticThreadLocal threadlocal=NewThreadLocal (); Static { //First step: Read the Hibernate configuration file, read the Hibernate.cfg.xml fileConfiguration con =NewConfiguration (). Configure (); //Step Two: Create the Service Registration Builder object, load all the configuration information in the configuration object, and store it in the registration serviceServiceregistrybuilder Regbuilder =NewServiceregistrybuilder (). Applysettings (Con.getproperties ()); //Create a registration serviceServiceregistry reg =Regbuilder.buildserviceregistry (); //Step Three: Create a session factoryFactory =con.buildsessionfactory (REG); } Public Staticsession Getlocalthreadsession () {session S= Threadlocal.get ();//gets the session under the current thread if(s = =NULL) {s= GetFactory (). Getcurrentsession ();//gets the session in the current thread, required in the Hibernate.cfg.xml file, see the description of the polygonThreadlocal.set (s);//saves the current session into the container of the current thread } returns; } Public Static voidclosesession () {Session s= Threadlocal.get ();//gets the session under the current thread if(s! =NULL) { //s.close ();//There is no need to close the session because the session is saved in the current thread//, the session will naturally be destroyed when the thread finishes executing .Threadlocal.set (NULL);//clears a session in the current thread } }}
2. Add Opensessioninviewfilter filter ( do not forget to configure the filter in Web. XML )
Public voidDoFilter (servletrequest request, servletresponse response, Filterchain Filterchain)throwsIOException, servletexception {Session s=hibernateutil.getthreadlocalsession (); Transaction T=NULL;Try {//Start a transactiont =s.begintransaction (); //Enter a series of filter chains to handle the corresponding action, business logic, and data layers Filterchain.dofilter (request, response); //Commit a transaction T.commit (); } Catch(Exception e) {if(t! =NULL) T.rollback ();//An unexpected rollback transaction occurred Throw Newruntimeexception (E.getmessage (), E); } finally{hibernateutil.closesession (); }}
===========================================
Getcurrentsession and opensession differences:
1, the session created by Getcurrentsession is bound to the current thread, and Opensession does not.
2, the thread created by Getcurrentsession is automatically closed after the transaction is rolled back or the thing commits, and opensession must be closed manually
3, getcurrentsession You need to add a configuration in the Hibernate.cfg.xml file:
<property name= "Current_session_context_class" >thread</ Property>
Iv. Summary
advantages and disadvantages of this solution:
1. Advantages: The use of threadlocal in addition to avoid the frequent creation and destruction of the session benefits, there is a particularly large benefit,
is the ability to do multi-threaded data isolation, you can avoid multiple threads simultaneously operate the same session
2. Disadvantages: If
Use interceptors to repeat the filter once again when the response is returned, extending the response time (improved: We can write the method written in the filter in a specific class, use the time to call)
Five: NOTE:
Threadlocal mainly solves the problem that the data in multi-threading is inconsistent with concurrency . Threadlocal provides a copy of the data that is accessed concurrently in each thread and runs the business through the access replica, which results in memory consumption, greatly reducing the performance cost of thread synchronization and reducing the complexity of thread concurrency control.
Threadlocal cannot use atomic types, only object types. Threadlocal is much simpler to use than synchronized.
Both threadlocal and synchonized are used to solve multi-threaded concurrent access. But there is an essential difference between threadlocal and synchronized.
1. synchronized is the mechanism by which a lock is used so that a variable or block of code can be accessed by only one thread at a time.
2. ThreadLocal provides a copy of the variable for each thread , so that each thread accesses a different object at a time, thus isolating data sharing from multiple threads. Synchronized, in contrast, is used to gain data sharing when communicating between multiple threads.
Synchronized is used for data sharing between threads, while threadlocal is used for data isolation between threads.
Of course threadlocal is not a substitute for synchronized, they deal with different problem domains. Synchronized is used to implement synchronization mechanisms and is more complex than threadlocal.
Hibernate learning notes-using threadlocal