views:

158

answers:

1

I implemented Dynamic DataSource Routing for Spring+Hibernate according to this article. I have several databases with same structure and I need to select which db will run each specific query.

Everything works fine on localhost, but I am worrying about how this will hold up in real web site environment. They are using some static context holder to determine which datasource to use:

public class  CustomerContextHolder {

   private static final ThreadLocal<CustomerType> contextHolder =
            new ThreadLocal<CustomerType>();

   public static void setCustomerType(CustomerType customerType) {
      Assert.notNull(customerType, "customerType cannot be null");
      contextHolder.set(customerType);
   }

   public static CustomerType getCustomerType() {
      return (CustomerType) contextHolder.get();
   }

   public static void clearCustomerType() {
      contextHolder.remove();
   }
}

It is wrapped inside some ThreadLocal container, but what exactly does that mean? What will happen when two web requests call this piece of code in parallel:

CustomerContextHolder.setCustomerType(CustomerType.GOLD);
//<another user will switch customer type here to CustomerType.SILVER in another request>
List<Item> goldItems = catalog.getItems();

Is every web request wrapped into its own thread in Spring MVC? Will CustomerContextHolder.setCustomerType() changes be visible to other web users? My controllers have synchronizeOnSession=true.

How to make sure that nobody else will switch datasource until I run required query for current user?

Thanks.

+2  A: 

Is every web request wrapped into its own thread in Spring MVC?

Yes, but this has nothing to do with Spring MVC, the container is doing that (the container has a thread pool and picks one of the them to handle each request).

Will CustomerContextHolder.setCustomerType() changes be visible to other web users?

No. A ThreadLocal is by definition local to a thread. From the javadoc:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

What you set in a ThreadLocal is not visible to other threads. You should be fine

Pascal Thivent