UPDATE: Solution right after question.
Usually, synchronization is serializing parallel requests within a JVM, e.
The spring framework solution as mentioned by Tomasz Nurkiewicz is accidentally correct in clustered environments only because the Servlet spec requires session consistency across multiple JVMs. Otherwise, it does not do a magic on its own for the scenarios where multiple requests are spread across different machines. See the discussion in this thread that sheds some light on the subject.
In general, don't rely on HttpServletRequest.getSession()
returning same object. It's easy for servlet filters to create a wrapper around session for whatever reason. Your code will only see this wrapper, and it will be different object on each request. Put some shared lock into the session itself. (Too bad there is no putIfAbsent
though).
As people already said, sessions can be wrapped by the servlet containers and this generates a problem: the session hashCode() is different between requests, i.e., they are not the same instance and thus can't be synchronized! Many containers allow persist a session. In this cases, in certain time, when session was expired, it is persisted on disk. Even when session is retrieved by deserialization, it is not same object as earlier, because it don't shares same memory address like when was at memory before the serialization process. When session is loaded from disk, it is put into memory for further access, until "maxInactiveInterval" is reached (expires). Summing up: the session could be not the same between many web requests! It will be the same while is in memory. Even if you put an attribute into the session to share lock, it will not work, because it will be serialized as well in the persistence phase.