如何为AbstractRoutingDataSource安全频繁的DataSource切换?

ser*_*erg 4 java spring hibernate

我根据这篇文章实现了Spring + Hibernate的Dynamic DataSource Routing .我有几个具有相同结构的数据库,我需要选择哪个数据库将运行每个特定的查询.

在localhost上一切正常,但我担心这将如何在真正的网站环境中保持.他们使用一些静态上下文持有者来确定要使用的数据源:

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

它被包装在一些ThreadLocal容器中,但究竟是什么意思呢?当两个Web请求并行调用此代码时会发生什么:

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

是否每个Web请求都包装在Spring MVC中的自己的线程中?将CustomerContextHolder.setCustomerType()变化是其他网络用户看到?我的控制器有synchronizeOnSession=true.

如何在我为当前用户运行所需查询之前确保没有其他人切换数据源?

谢谢.

Pas*_*ent 6

是否每个Web请求都包装在Spring MVC中的自己的线程中?

是的,但这与Spring MVC无关,容器正在这样做(容器有一个线程池,并选择其中一个来处理每个请求).

CustomerContextHolder.setCustomerType()更改是否会对其他Web用户可见?

ThreadLocal根据定义,A 是线程的本地.来自javadoc:

该类提供线程局部变量.这些变量与它们的正常对应物的不同之处在于,访问其中的每个线程(通过其getset方法)具有其自己的,独立初始化的变量副本.ThreadLocal实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户ID或事务ID).

setThreadLocal其他线程中看不到什么.你应该没事