Java – how do I get exclusive access to certain session entries?
Due to the remote invocation feature of rest services, they are in a state of constantly becoming competitive conditions One of the daily resources of the competition is the meeting To be practical, you need to be able to lock resources at the beginning of the process and release them after completing the task
Now my question is, does spring session have any functionality to handle race conditions in session entries?
Or any other library / framework in java!
Solution
If you are using spring controllers, you can use
RequestMappingHandlerAdapter. setSynchronizeOnSession-boolean-
This will synchronize each controller method when the session exists
HttpSession. SetAttribute is thread safe However, getattribute followed by setAttribute must be manually secured
synchronized(session) { session.setAttribute("foo","bar"); session.getAttribute("foo"); }
The same thing can be done in the case of spring session beans
synchronized(session) { //do something with the session bean }
#Edit
If multiple containers have ordinary spring session beans, you must use sticky sessions This ensures that a session state is stored in a container and accessed every time the same session is requested This must be done on the load balancer with the help of BIGIP cookies Rest will exist in the same way as a single container for a single session, so locking the session is sufficient
If you want to use session sharing across instances, support containers such as Tomcat and jetty
These methods use back - end databases or other persistence mechanisms to store state
For the same purpose, you can try using spring session Redis is very simple to configure Because redis is single threaded, it can ensure that an instance of an item is accessed atomically
The above methods are non - invasive Both the database and redis based methods support transactions
However, if you want better control over distributed state and locking, you can try using distributed data grids, such as hazelcast and gemfire
I personally worked with hazelcast, which does provide methods to lock entries made in the map
#EDIT2
Although I think transaction processing should be sufficient for spring session and redis to ensure that you need distributed locking The locked object must be obtained from redis itself Since redis is single threaded, personal implementations can also use things like incr
The algorithm will be as follows
//lock_num is the semaphore/lock object lock_count = INCR lock_num while(true) { if(lock_count != 1) { DECR lock_num } else { break } wait(wait_time_period) } //do processing in critical section DECR lock_num
Fortunately, however, spring has provided this distributed lock implementation through redislock registry More documents are available in usage is here
If you decide to use ordinary jedis without springs, here is jedis distributed lock: jedis lock
//from https://github.com/abelaska/jedis-lock Jedis jedis = new Jedis("localhost"); JedisLock lock = new JedisLock(jedis,"lockname",10000,30000); lock.acquire(); try { // do some stuff } finally { lock.release(); }
Both should work like hazelcast locking