如何为AbstractRoutingDataSource制作安全频繁的DataSource开关? [英] How to make safe frequent DataSource switches for AbstractRoutingDataSource?

查看:158
本文介绍了如何为AbstractRoutingDataSource制作安全频繁的DataSource开关?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我根据这个实现了Spring + Hibernate的动态数据源路由文章。我有几个数据库具有相同的结构,我需要选择哪个数据库将运行每个特定的查询。

本地主机上的一切工作正常,但我担心这将如何在真实的网站环境中。他们正在使用一些静态上下文持有者来确定使用哪个数据源:

  public class CustomerContextHolder {

私有静态最终ThreadLocal< CustomerType> contextHolder =
new ThreadLocal< CustomerType>();

public static void setCustomerType(CustomerType customerType){
Assert.notNull(customerType,customerType不能为null);
contextHolder.set(customerType);


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


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




$ b

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

  CustomerContextHolder.setCustomerType(CustomerType.GOLD); 
//<另一个用户将在这里将客户类型切换到另一个请求中的CustomerType.SILVER>
列表<项目> goldItems = catalog.getItems();

每个Web请求都被包装到Spring MVC的自己的线程中吗?其他Web用户可以看到 CustomerContextHolder.setCustomerType()更改吗?我的控制器有 synchronizeOnSession = true

如何确保没有人会切换数据源,直到我运行所需的查询

谢谢。


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


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

没有。 ThreadLocal 是线程本地的。从javadoc:


该类提供线程局部变量。这些变量不同于它们的正常副本,因为每个访问一个线程的线程(通过它的 get set 方法)自己的,独立初始化的变量副本。 ThreadLocal 实例通常是希望将状态与线程关联的类(例如用户ID或事务ID)中的私有静态字段。

你在 ThreadLocal 中设置 code>对其他线程不可见。你应该很好


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.

解决方案

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

这篇关于如何为AbstractRoutingDataSource制作安全频繁的DataSource开关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆