Как сделать безопасными частые переключатели DataSource для AbstractRoutingDataSource? - PullRequest
3 голосов
/ 15 июня 2010

Я реализовал динамическую маршрутизацию источника данных для Spring + Hibernate в соответствии с этой статьей .У меня есть несколько баз данных с одинаковой структурой, и мне нужно выбрать, какая БД будет выполнять каждый конкретный запрос.

Все отлично работает на 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();
   }
}

Он заключен в некоторый контейнер ThreadLocal, но что именно это означает?Что произойдет, когда два веб-запроса вызывают этот фрагмент кода параллельно:

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

Каждый веб-запрос упакован в свой собственный поток в Spring MVC?Будут ли изменения CustomerContextHolder.setCustomerType() видны другим пользователям сети?У моих контроллеров есть synchronizeOnSession=true.

Как сделать так, чтобы никто больше не переключал источник данных, пока я не выполню требуемый запрос для текущего пользователя?

Спасибо.

1 Ответ

5 голосов
/ 15 июня 2010

Каждый ли веб-запрос упакован в собственный поток в Spring MVC?

Да, но это не имеет ничего общего с Spring MVC, это делает контейнер (контейнер имеет пул потоков и выбирает один из них для обработки каждого запроса).

Будут ли изменения CustomerContextHolder.setCustomerType () видны другим пользователям сети?

Нет. A ThreadLocal по определению является локальным для потока. Из Javadoc:

Этот класс предоставляет локальные переменные потока. Эти переменные отличаются от своих обычных аналогов тем, что каждый поток, который обращается к одному (с помощью своего метода get или set), имеет свою собственную, независимо инициализированную копию переменной. ThreadLocal экземпляры, как правило, являются частными статическими полями в классах, которые хотят связать состояние с потоком (например, идентификатор пользователя или идентификатор транзакции).

То, что вы set в ThreadLocal не видно другим потокам. Вы должны быть в порядке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...