1

When working on an ASP.NET application, I discovered that placing something in the session cache, or really, accessing variables in the session cache, caused my Ajax queries to stop being asynchronous. I learned that this was because the session basically blocks - if I fire two Ajax requests from my browser at the same time, and the first one takes a bit to return, the session is locked in the first request until that request is completed, at which point my second Ajax request starts working.

In PHP I gather that there is an option to close the session for writing (and / or open it in a read-only way) so that session variable access is non blocking and things stay asynchronous.

I'm building an application that will be Java, probably running on Tomcat (though I could change to some other container if I needed) and I am not able to find out whether Java has the same issue (session variable reads block) or has the same remedy (early close, read only mode). Has anyone encountered that issue before?

mindas
  • 26,463
  • 15
  • 97
  • 154
Mikeb
  • 6,271
  • 3
  • 27
  • 41

2 Answers2

2

In Tomcat, HttpSession is implemented in org.apache.catalina.session.StandardSession (source here).

If you look at the source, you will see that calls to HttpSession.getAttribute(String) and HttpSession.setAttribute(String, Object) are pretty much channelled to a ConcurrentHashMap without any additional synchronization.

This means that these calls derive the contract of ConcurrentHashMap. Quoting its Javadoc:

  • retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access. <..> Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove)
  • The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary.
mindas
  • 26,463
  • 15
  • 97
  • 154
  • so, essentially, you just make sure you don't do something like `session.put(key, someTimeExpensiveMethod());` – Victor Sorokin Oct 24 '12 at 21:33
  • 2
    @VictorSorokin: this can't be an issue, `someTimeExpensiveMethod()` will be evaluated before `put()` is called and if method is synchronized, `someTimeExpensiveMethod()` runs before it enters synchronized block. It's call by value, not by name. – Tomasz Nurkiewicz Oct 24 '12 at 21:38
  • yes, my bad. perhaps, then, OP uses pre-1.5 JDK which has no `ConcurrentHashMap`? :) – Victor Sorokin Oct 24 '12 at 21:42
  • @VictorSorokin I thought OP was *considering* to use Java/Tomcat and was asking if it ill behaves similar to PHP/ASP.NET. Or by OP you meant http://stackoverflow.com/a/616723/162634? – mindas Oct 24 '12 at 21:44
  • oops, my bad again. I thought OP had blocking issue on Java, not ASP. – Victor Sorokin Oct 24 '12 at 21:46
0

It looks like blocking takes place because of threads synchronization of access to HttpSession as described in this SO answer

So, it must be that 2nd request is blocked only while 1st one is working with HttpSession (or if you have some shared lock which is held for long time by 1st request, but this has nothing to do with Tomcat).

Since this synch is required by Servlets spec, you shouldn't try to violate it. Instead, make your app so it minimizes time it needs to read from or write to HttpSession.

Additionally, as I wrote above, blocking may occur if you have additional lock which makes several requests execute sequentially. Try to make several thread dumps of Tomcat when you have sent 2nd request to Tomcat and see if there's any such lock which is waited by 2nd requet for.

Community
  • 1
  • 1
Victor Sorokin
  • 11,878
  • 2
  • 35
  • 51