Announcement Announcement Module
Collapse
No announcement yet.
advice needed on DI and thread-safety Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • advice needed on DI and thread-safety

    I'm developing two very similar web-apps. They both use much of the same code except the front-end is different and the backend SQL statements differ slightly... the middletier is almost the same. Both of the web-apps interact with the middletier and backend through a facade-like controller. Each request creates a new facade to interface with business logic and the backend. The facade itself creates the DAO objects.

    For these apps it makes sense to me to inject the SQL class (queries reside in one class) into the DAO class(es) wrather than having tocode different DAO classes for each app. I am unsure about concurrency issues though. How do I ensure that the SQL classes will not be reused among different user requests or ensure that they are used in a thread-safe manner?

    thanks

  • #2
    I'm a little confused by some of the terms you've used. Facade is a somewhat overloaded term that can mean different things. Controller definitely has specific meaning with respect to Spring- meaning the "C" in MVC architecture- or more specifically, the "C" in Spring MVC. So I guess I'm not sure what you mean by "facade-like controller."

    But...

    I do understand your plight- DAOs that differ only in the SQL that is used for each of the two apps. Your approach sounds fundamentally sound. Abstract queries away from the DAOs and encapsulate them in an additional class- maybe named AppASqlProvider and AppBSqlProvider- both implementing a SqlProvider interface of your own design.

    In each of your two applications, the appropriate SqlProvider can be injected into each DAO. You could use an abstract parent bean to simplify this sort of configuration.

    Anyhow- back to the elements of your approach that I might call into question...

    You mentioned that your "facade-like controller" "creates" the DAOs. That sounds inefficient and also sounds contrary to the spirit of dependency injection. DAOs are generally singletons and therefore are NOT throwaways. They should be injected at application startup into whichever higher-level components depend on them. In most architectures, that would be a service layer. ("Service" means it provides a service and does not necessarily imply it is remote.)

    Regarding thread-safety- it goes without saying that a singleton will be used to process many requests and might even be used in the processing of multiple threads concurrently. This being the case, it's essential that singletons are stateless. Statelessness- although it does not guarantee thread-safety- does PROMOTE thread safety.

    To be stateless, don't hold request-specific data in the DAO's instance variables. Instance variables should be reserved only for holding references to things that are less volatile- not subject to change- such as the DAO's own dependencies- like the SqlProvider we discussed.

    It goes without saying that the statelessness needs to extend to the dependencies of a stateless component at well.

    Does this help any?

    Comment


    • #3
      Thanks for the reply. Yes, "facade-like controller" is somewhat ambiguous... what I mean is its just a plain old facade, as in the facade pattern. As it exists now, each of my controllers (real Spring MVC controllers ) will create a new facade object for each request to access backend functionality. I know that the facade object should probably be injected as a singleton into the controller, but quite frankly the whole issue of thread-safety makes me uneasy because I'm not 100% sure I understand it with respect to spring mvc controllers. Maybe this is a good time to clarify it for me or point me to some real-world examples.

      If for example we had two request threads, at what point during the execution of a controller (lets use a SimpleFormController), can one thread interrupt the other and proceed with its execution? My basic understanding is that once a thread has begun executing a controller method (be it initBinder(), formBackingObject(), or onSubmit()), then it must finish execution of that method before another thread can execute. Is this correct?


      Thanks!

      Comment


      • #4
        You need to back off of Spring a little bit and get handle on threading in Java. Spring does not interfere with normal threading semantics in any way.

        In Java, multiple threads can execute the same piece of code concurrently, the only thing that prevents such a thing from happening is by synchronizing a method- meaning that only one thread may execute the method at a time- or by using a synchronized block- this is a finer-grained strategy wherein a thread must obtain a lock on some object in order to execute a piece of code. This means that only one thread at a time can run that piece of code. When it exits the block, the thread relinquishes the lock and another thread is free to obtain the lock and execute that piece of code.

        Again, Spring does not interfere with this in any way.

        If we start to dig down into how Spring MVC works, this is what we'd find- incoming HTTP requests are handled by your application server- Tomcat, WebSphere, WebLogic, what-have-you. Details of that request are encapsulated in an HttpRequest and handed off to a servlet- Spring's DispatcherServlet. DispatcherServlet is threadsafe- meaning multiple threads can execute its code concurrently. Strictly speaking, all servlets are supposed to be coded in a threadsafe manner because servlets are implicity singletons on account of the fact that your application server will only create one instance of each servlet described in your web.xml.

        Controllers are typically singletons. I won't proclaim that they must be singletons, but I have yet to see a case where they are not.

        Since controllers are singletons, their dependencies must be as well. So, your facade, or service layer would be singletons. This "need" to be a singleton kind of propagates virally down through the layers of your applications- all the way down to the DAOs.

        So, generally speaking, in a Spring application, all your major components are singletons. This means there is only one of each. It does not mean, however, that multiple threads can't use those components concurrently. They certainly can. This is precisely why code should be made threadsafe.

        So, getting back to my previous note, the best way to promote thread-safety is to code your components so that they are stateless. This means avoiding the use of instance variables for storing data specific to the request. Instance variables should only be used to store things that are common to all requests- for instance- configuration, or one component's dependencies on others.

        Just in case you are unaware, multipe threads executing the same piece of code will never have any contention over local variables since local variables in Java are scoped to the thread of execution.

        So- going back to the whole stateless thing- what if you abolutely need a stateful component (e.g. need to use instance variables) for some reason? In such a case, that component should be a request-scoped or session-scoped bean- whichever is more appropriate. The way this works under the covers is that any singleton depending on a request-scoped bean is actually injected with a dynamically-generated (by Spring) singleton proxy which- upon each method invocation- locates or instantiates/caches the bean in the indicated scope and passed the method call along to that bean.

        Bottom line is- heavily favor singletons. Keep components stateless. Deal with the outliers as they arise.

        Comment


        • #5
          Ah, right. The one key piece of info I had forgotten was that each thread will have its own set of locally scoped variables. Its all coming together now.

          thanks

          Comment

          Working...
          X