2016-04-29 2 views
0

В моем проекте spring-jdbc у меня есть класс под названием DBStuff, который я использую для подключения к db и создания простых операций db. Это веб-проект, и есть пользователи, поэтому, естественно, я использую механизм сеанса. Когда мне нужно получить данные запроса в DBStuff классе, я использую эту строку кода ниже:Является ли RequestContextHolder потокобезопасным?

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 

Но, нет никакого объяснения, что если RequestContextHolder потокобезопасно или нет. Даже официальный представитель весны forum не имеет на это ответа. Из-за использования сервлета, я должен обеспечить потокобезопасный характер для пользователей.

По определению RequestContextHolder определяется как «Класс держателя, чтобы выставить веб-запрос в виде связанного с потоком объекта RequestAttributes». Но я не уверен, что «thread-bound» означает потокобезопасность.

+0

Это поточно, но почему вы связывание вашего слоя доступа к данным на веб-слой ... Это запах кода и imho сигнал, что вы делаете что-то неправильно. –

+0

Уровень данных DataAccess и веб-уровень являются отдельными, но каждый пользовательский запрос сохраняет свои данные для входа, которые играют огромную роль в операциях БД. Должен ли я изменить класс DataAccess на прототип? Но если я это сделаю, разве это не стоит слишком много памяти и производительности для моей системы? –

+0

Нет, они не разделены ... Уровень данных зависит от веб-слоя. Вы не можете взять свой класс dbaccess и поместить его на сервер, не поддерживающий веб-интерфейс, поскольку он тесно связан с javax.servlet и веб-пакетами Spring. Следовательно, связь между сетью и доступом к данным. Если вам это нужно, либо передайте этот материал в аргументе метода, либо сохраните его в «ThreadLocal», но не пропустите веб-детали в каких-либо других, а затем связанных веб-классах. –

ответ

4

"thread-bound" означает, что каждый поток имеет собственную копию данных, поэтому он является потокобезопасным.

Он использует ThreadLocal для этого

private static final ThreadLocal<RequestAttributes> requestAttributesHolder = 
     new NamedThreadLocal<RequestAttributes>("Request attributes"); 

public static RequestAttributes getRequestAttributes() { 
    RequestAttributes attributes = requestAttributesHolder.get(); 
    if (attributes == null) { 
     attributes = inheritableRequestAttributesHolder.get(); 
    } 
    return attributes; 
} 

requestAttributesHolder.get() возвращает RequestAttributes для текущего потока, то есть поток, обработать HTTP запрос. У каждого запроса есть собственный поток.

Метод get() из ThreadLocal использует карту для связанных данных в Thread.currentThread()

public T get() { 
    Thread t = Thread.currentThread(); 
    ThreadLocalMap map = getMap(t); 
    if (map != null) { 
     ThreadLocalMap.Entry e = map.getEntry(this); 
     if (e != null) 
      return (T)e.value; 
    } 
    return setInitialValue(); 
} 

When and how should I use a ThreadLocal variable?

+0

Но класс DBStuff является одноточечным, не делает ли RequestContextHolder привязанным к потоку этого класса? –

+0

Это правда, если у меня есть запрос и продолжайте с ним в классе. Но проблема в том, что я пытаюсь получить запрос внутри этого одноэлементного класса «DBStuff». Если 'RequestContextHolder' связан с текущим потоком, то как он может обрабатывать два одновременных запроса? –

+0

@cihanseven i update –

Смежные вопросы