Optimize JDBC update and retrieval logic
Current optimizations on JDBC Session is good but still have large rooms for optimizations. Each commit of session is resetting state of session and after that each update there is another get call for session as this by getRequestedSessionId:
else {
S session = wrappedSession.getSession();
saveSession(session);
String sessionId = session.getId();
if (!isRequestedSessionIdValid()
|| !sessionId.equals(getRequestedSessionId())) {
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this,
this.response, sessionId);
}
}
- For a simple request to server there is two
commitcalls. - One of them are calling UPDATE session.
- Each commit is followed by SELECT.
- 3 SELECT, 2 UPDATE calls are triggered by each request. These are transactional and thus it around 20 SQL statements are executed per call.
I can understand that session must be committed as early as possible since client issues can happen, but following an UPDATE with a SELECT is not ideal.
Current optimizations on JDBC Session is good but still have large rooms for optimizations.
I'm not sure this is the case - we've done what we can at SessionRepositoryFilter level. Typically you'd address the problem by caching at repository level, but this doesn't make sense here as it's too complex and we already have RedisOperationsSessionRepository and HazelcastSessionRepository.
You'll get some improvements in when we implement #1046, but if you're performance constrained I'd strongly suggest to consider using either Redis or Hazelcast. Relational database is by far the most limited option for a session store.
Would you please tell me, why there is a need to reset session to null after committing it? Since it is same session, resetting is not necessary I believe. This can cause simply reduce 1 update, 2 select easily.
See this comment:
You cannot do that - as you are aware
SessionRepositoryimplementations handle various internal details when performing save operation, like tracking delta of changes and handling session id changes, so obtaining a fresh session is the only safe thing to do here.
Would you give me an example and explanation why it is a problem for any SessionRepository implementation?
The point is that SessionRepository#save contract doesn't offer guarantees to do that safely. If it had returned a session instead of void that would've been a different story.
It is not returning a session since some implementations can implement a session which is immediately saving changes. So a correct implementation of this method either does nothing (since there is no need to update which is already updated) or saves session immediately. Relying on session in memory at the time on commit is totally safe. It must be same as the latest value of repository.
Here is the relevant section of SessionRepository#save.
* Some implementations may choose to save as the {@link Session} is updated by
* returning a {@link Session} that immediately persists any changes. In this case,
* this method may not actually do anything.
There might be some async persisting save operations on repository? If there is a case like this, relying on datastore is very dangerous since it can load session before persisted into repository and load stale data.
Shortly, I think is invalidating session in that phase is useless since it will be same as the session in the repository.