问题描述
我根据。我有几个数据库具有相同的结构,我需要选择哪个数据库将运行每个特定的查询。
本地主机上的一切工作正常,但我担心这将如何在真实的网站环境中。他们正在使用一些静态上下文持有者来确定使用哪个数据源:
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没有任何关系,容器正在这样做(容器有一个线程池,并选择其中一个来处理每个请求)。
没有。 是线程本地的。从javadoc:
你在 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.
解决方案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).
No. A ThreadLocal is by definition local to a thread. From the javadoc:
What you set in a ThreadLocal is not visible to other threads. You should be fine
这篇关于如何为AbstractRoutingDataSource制作安全频繁的DataSource开关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!