2011-11-30 2 views
1

개발자가 비즈니스 논리에만 집중해야하므로 App Server가 스레딩을 처리한다는 것을 알고 있습니다 ... 하지만 예제를 고려하십시오. 상태 비 저장 EJB에는 CountManager 유형의 구성원이 있습니다.EJB에서 멀티 스레딩을 할 때주의해야 할 사항은 무엇입니까?

@WebService 
@Stateless 
public class StatelessEJB { 
    private CountManager countManager; 
    ... 
    public void incrementCount() {countManager.incrementCount();} 
    public int getCount(){return countManager.getCount();} 
} 

그리고 CountManager

public class CountManager { 
    public void increaseCount() { 
    // read count from database 
    // increase count 
    // save the new count in database table. 
    } 

    public int getCount() { 
    // returns the count value from database. 
    } 
} 

개발자는 여기에 멀티 스레딩에 대해 생각해야한다. CountManager를 EJB로 만들면 문제가 해결되지 않을 것으로 생각됩니다. 개발자가주의해야 할 일반적인 가이드 라인은 무엇입니까?

업데이트 : 코드가 변경되었습니다. EJB의 메소드가 웹 서비스로 노출되어 있으므로 클라이언트가 호출하는 순서를 제어 할 수 없다고 가정합니다. 트랜잭션 속성은 기본값입니다. 다중 스레드 시나리오에서이 코드가 올바르게 작동합니까?

+0

"이 코드는 스레드로부터 안전하지 않습니다"라고 설명하는 이유를 설명하십시오. 어떤 작업을 어떤 순서로 실행하고 어떤 결과를 기대합니까? EJB 동시성 액세스 또는 동시 데이터베이스 액세스가 걱정됩니까? 기본 EJB 인'TransactionAttribute'를 사용하고 있습니까? –

+0

@PiotrNowicki가 질문을 업데이트하고 언급 한 진술을 삭제했습니다. 나는 결과가 정확하지 않다는 것을 두려워한다. – anergy

답변

2

EJB가 스레드로부터 안전하다는 사실은 다른 메소드 호출이 일관된 결과를 제공한다는 것을 의미하지는 않습니다.

EJB는 당신에게 특정 EJB 인스턴스의 모든 방법을 정확히 하나의 스레드에 의해 실행됩니다 확실성을 제공합니다. 이렇게하면 여러 사용자가 EJB의 다른 인스턴스에 액세스하고 일관성없는 결과가 나올 수 있습니다.

CountManager은 Stateless EJB에서 상태를 보유한다는 것을 의미하는 일반 Java 클래스 인 것 같습니다. 이것은 좋지 않으며 EJB 쓰레드 안전성은 그런 경우에 당신을 보호하지 못한다. 객체는 여러 EJB 인스턴스을 통해 동시에 액세스 할 수 있습니다. (트랜잭션을 시작 - 기본 TransactionAttribute) 고객의 첫 번째 메소드 호출 StatelessEJB.incrementCount() 사이

과 (새로운 트랜잭션을 시작) 두 번째 클라이언트의 메소드 호출 StatelessEJB.getCount() 많은 일들이 일어날 수와 count의 값은 변경 될 수 있습니다.

EJB로 변경하면 더 이상 안전하지 않을 것이라고 생각합니다. 그것보다 SLSB라면 여전히 어떤 상태도 가질 수 없습니다. 상태가 EJB 필드 변수로 인식되었지만 데이터베이스가 데이터를 가져온 경우 분명히 나은 것보다 트랜잭션이 실제 도움이되지 않습니다. WebService 클라이언트가 여전히이 두 가지 메소드를 개별적으로 실행하므로 서로 다른 두 트랜잭션에 상주하기 때문입니다.

간단한 솔루션을하는 것입니다 :

  • 데이터베이스 당신의 EJB 트랜잭션과 동기화 할 수 있습니다 (SLSB에없는 상태),
  • 를 사용하여 트랜잭션 내에서 이러한 방법 모두 (같은 incrementAndGet(-) 방법을 실행 WebService 클라이언트 용).

당신이 얻을 수있는 결과가 일관성이있을 때보 다 공정하게 확신 할 수 있습니다.

+0

감사합니다, 두 가지, 당신의 대답은 위의 로페즈의 답을 무효로 만듭니다. 권리? 둘째, StatelessEJB에 CountManager 변수가있을 경우 상태가 왜 그렇게됩니까? 국가는 실제로 데이터베이스에 있습니다. 그렇지 않습니까? – anergy

+0

아니요, 오스카의 대답은 트랜잭션 및 데이터베이스 중요성에 대해 이야기하고 트랜잭션에 참여하는 것처럼 보입니다. –

+0

네 말이 맞아. 나는 POJO가 데이터베이스에 접근하고 있다는 것을주의 깊게 읽지 않고 'CountManager' 내에 상태를 유지한다고 가정했다. Dependency injection-less POJO (적어도 생성자에서 인스턴스화하는 경우)는 괜찮습니다. 문제는 데이터베이스에 액세스하는 방법과이 액세스가 EJB 트랜잭션 인식 일지 여부입니다. –

2

실제로는 동기화 또는 멀티 스레딩 문제가 아니라 트랜잭션 동작 문제입니다.

위의 코드는 EJB 내부에서 실행되는 경우 트랜잭션 지원을 데이터베이스에 위임하여 경쟁 조건을 처리합니다. 격리 레벨 및 트랜잭션 속성에 따라 데이터베이스는 동시 액세스 및/또는 수정이 있더라도 정보가 일관성있게 유지되도록 기본 테이블을 잠그는 것을 처리 할 수 ​​있습니다.

관련 문제