2009-03-06 4 views
11

우리 모두는 웹 계층에서 여러 요청을 처리하는 주어진 Servlet 인스턴스가 하나만 존재할 가능성이 있음을 알고 있습니다. 이로 인해 인스턴스 변수에 스레딩 문제가 발생할 수 있습니다.EJB를 인스턴스 변수로 서블릿에 삽입하는 것이 안전합니까?

@EJB 주석을 사용하여 EJB를 인스턴스 변수로 서블릿에 삽입하는 것이 안전한가요?

EJB의 동일한 인스턴스가 동시에 여러 요청을 처리 할 것이라는 가정하에 초기 본능은 아니오입니다. 이것은 또한 다른 프로그래머의 본능이 될 것 같습니다 : Don't inject to servlets

그러나 나는 잘못된 결론으로 ​​뛰어 들었습니다. 분명히 서블릿에 주입되는 것은 프록시이며, 컨테이너는 실제로 다른 인스턴스로 각 요청을 처리하고 스레드 안전성을 유지합니까? 이 포럼에서 제안하는대로 : Do inject to servlets

많은 의견이 일치하는 것으로 보입니다. 정확합니까?

답변

3

참조 "서블릿에 주입하지 마십시오"는 ejbs 또는 @ejb 주석에 대해 언급하지 않았습니다. PersistenceContext와 같은 스레드로부터 안전하지 않은 객체에 대해서는 언급하지 않습니다.

EJB 사양에 따라 서블릿 (EJB 3.0 사양 (JSR-220) - 섹션 3.1)을 비롯한 다양한 원격 클라이언트에서 ejbs에 액세스 할 수 있습니다. @EJB annotation을 사용하여 ejb 삽입하기는 JNDI 네임 스페이스에서 ejb 객체를 찾지 못하도록하는 의존성 주입 (3.4.1 절)을 통해 EJB 인터페이스를 얻는 방법이다. 따라서 EJB 획득과 관련하여 @EJB 주석에 특별한 것은 없습니다.

따라서 EJB 3.0 스펙을 기반으로하면 @EJB 주석을 사용하여 서블릿에서 ejbs를 얻는 것이 일반적인 방법입니다.

+0

이 답변은 가능한 한 정확하지만 OP의 스레드 안전 문제를 해결하지 못합니다. 나는 아래의 inferreddesign의 대답이 올바른 것임을 믿습니다. –

+0

@Inject (CDI, JEE 6)를 주입 한 EJB는 안전 할 것입니다. 맞습니까? – marcus

0

간단한 대답은 안전하다는 보장이 없다는 것입니다.

이유는 EJB 홈 인터페이스가 스레드로부터 안전해야한다는 EJB 사양에 명시적인 내용이 없기 때문입니다. 이 스펙은 서버 측 파트의 동작을 간략하게 설명합니다. 클라이언트 골격은 실제로는 스레드로부터 안전하지만 사용중인 라이브러리에 의해 어떻게 구현되는지 살펴 봐야합니다. 어노테이션 파트는 서비스 로케이터로 확장되어 아무 것도 사지 않습니다.

11

EJB가 Stateless 인 경우 서블릿 인스턴스 변수로 서블릿에 EJB를 삽입하는 것이 안전합니다. 서블릿에 Stateful Bean을 주입하면 안됩니다.

스테이트 풀 값 (예 : 지속성 컨텍스트)을 보유하고있는 인스턴스 변수를 보유하지 않도록 EJB 스테이트리스를 구현해야합니다. 지속성 컨텍스트를 사용해야하는 경우 EJB의 메소드에서 인스턴스를 가져와야합니다. PersistenceContextFactory를 EJB 인스턴스 변수로 사용하면 EJB의 메소드에서 팩토리에서 엔티티 관리자의 인스턴스를 가져올 수 있습니다.

PersistenceContextFactory는 스레드로부터 안전하므로 인스턴스 변수에 삽입 할 수 있습니다.

는만큼 당신이 위에서 언급 한 규칙을 준수하는 한, 그것은 스레드 안전은 서블릿

1

그것은 반반 년대에 비 저장 Bean을 주입해야한다.

무 상태 세션 콩을 주입 할 수 있으며 안전합니다.이것은 스텁의 단일 인스턴스가 사용되는 경우에도 메소드에 대한 액세스가 컨테이너에 의해 직렬화되기 때문입니다.

내가 추측 한 디자인은 이 아닌 것으로 생각합니다.. 상태없는 세션 빈이 영속 컨텍스트를 사용하는지는 중요하지 않습니다. 하나의 호출자 만이 동시에 하나의 빈 인스턴스에 액세스 할 것이므로 영속 컨텍스트가 쓰레드에 안전하지 않더라도 EJB는 다중 컨텍스트 액세스를 막습니다. 모든 세션 bean 메소드에 synchronized 키워드가 적용된 것처럼 생각하면됩니다.

EJB를 서블릿에 주입하는 주된 문제점은 성능이라고 생각합니다. 단일 스텁 인스턴스는 세션 빈 메서드가 실행될 때까지 대기하는 동안 여러 요청이 대기 중일 때 주요 경쟁 영역이됩니다.

+0

스텁은 동기화되지만 실제 작업을 수행하기 위해 풀링 된 EJB 중 하나에 신속하게 디스패치 할 것으로 예상됩니다. 스텁이 전체 호출 중에 잠금을 유지하지 않는 한 매우 나쁜 구현 선택입니다 ... – marcus

관련 문제