Thursday, May 11, 2006

Pojo-based Middle Tier Vs. Thread Safe

A post popped up on the Spring mailing list regarding thread safety. The poster wanted to know if the "singleton, POJO-based service model" Spring recommends for a typical webapp is actually a good thing concurrency and scalability wise.

In my consulting work, I've been asked exactly this same question: When you're talking about a web-tier interfacing with a co-located, POJO-based middle tier, what does it mean to be "thread safe"? When do you have to worry about concurrency?

A guiding principle to heed is "never share caller specific (aka request specific) state between threads". Local variables are one way of achieving this (for example, declared within a thread-safe method of a request handler or servlet). ThreadLocals are another. A third is use of stateless service collaborators, the subject of this blog.

When you're talking about a traditional stateless service object--which is typically what these POJOs business facades are--a single instance typically serves all client requests. While such a singleton service may have its own internal state, it doesn't manage caller-specific state. Everything it needs from callers it gets within a caller's local thread of execution via method parameters. In addition, the internal collaborators these shared services often deal with: data sources, caches, transaction managers, or other resources, are already thread safe themselves (or they sure as heck better be!) :-)

Hence, there is no need to worry about synchronization within your service facades unless you manage shared read/write state yourself (an exceptional case in my experience). There is also no value in service instance pooling: a singleton stateless service object can serve all clients, and can easily be scaled across a cluster. There is value in resource pooling, but that's typically already handled transparently for you, by good infrastructure providers (like jakarta common's dbcp, for database connection pooling).

So, in summary, there is often no need to create a new, local service object per request (e.g a one shot "command object") unless there is caller specific state that object needs to be initialized with (in cases where the command pattern makes sense.) In the case where the per-request Command pattern does make sense, you can easily implement this "one-shot command" in Spring by declaring a prototype bean definition, retrieving a new instance instantiated, configured, and wired by the Spring IoC container on a per-request basis.

Trackback URL: http://jroller.com/trackback/kdonald/Weblog/when_shared_state_is_thread

No comments: