2010-04-22 2 views
5

@Singleton, @Schedule 및 @Timeout 주석으로 간단한 예제를 작성하여 문제가 해결 될 경우 시도해보십시오.타이머 서비스 in ejb 3.1 - 호출 시간 제한 문제 호출

시나리오는 다음과 같습니다. EJB는 5 초마다 'check'함수를 호출하고 특정 조건이 충족되면 비동기 방식으로 긴 실행 프로세스를 호출하는 단일 작업 타이머를 만듭니다. (일종의 대기열 구현 유형의 것). 그런 다음 검사를 계속하지만 장기 실행 프로세스가있는 동안에는 다른 프로세스가 시작되지 않습니다.

아래 코드는 내가 작성한 코드이지만, 비동기 호출처럼 보이기 때문에이 솔루션이 작동하지 않습니다. 실제로 만드는 것은 @Schedule 메서드를 차단하는 것입니다.

@Singleton 
@Startup 
public class GenerationQueue { 

    private Logger logger = Logger.getLogger(GenerationQueue.class.getName()); 

    private List<String> queue = new ArrayList<String>(); 

    private boolean available = true; 

    @Resource 
    TimerService timerService; 

    @Schedule(persistent=true, minute="*", second="*/5", hour="*") 
    public void checkQueueState() { 

     logger.log(Level.INFO,"Queue state check: "+available+" size: "+queue.size()+", "+new Date()); 

     if (available) { 

      timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false)); 
     } 

    } 

    @Timeout 
    private void generateReport(Timer timer) { 

     logger.info("!!--timeout invoked here "+new Date()); 

     available = false; 

     try { 

      Thread.sleep(1000*60*2); // something that lasts for a bit 

     } catch (Exception e) {} 

     available = true; 

     logger.info("New report generation complete"); 

    } 

여기에 무엇이 누락 되었습니까? 아니면 다른 시도해야합니까? 환영 어떤 아이디어 : 글래스 피시 3.0.1 최신 빌드와

테스트 - 싱글에 대한

답변

11

기본 @ConcurrencyManagement이 LockType.WRITE의 기본 @Lock와 ConcurrencyManagementType.CONTAINER을 언급하는 것을 잊었다. 기본적으로 generateReports를 포함한 모든 메소드가 synchronized 키워드로 효과적으로 표시된다는 것은 generateReport가 실행되는 동안 checkQueueState가 차단된다는 것을 의미합니다.

ConcurrencyManagement (ConcurrencyManagementType.BEAN) 또는 @Lock (LockType.READ)의 사용을 고려하십시오. 두 가지 제안 모두 도움이되지 않으면 글래스 피어 버그를 발견했다고 생각됩니다.

서버가 오프라인 인 경우에도 checkQueueState 메소드가 5 초마다 실행되도록 보장 할 필요가 없으므로 persistent = false를 원할 수도 있습니다. 즉, 서버를 다시 온라인 상태로 전환 할 때 컨테이너에서 "catch ups"을 실행하지 않아도됩니다.

+0

감사합니다. Concurency를 ConcurrencyManagementType.BEAN으로 변경하면 문제가 해결되고 예 (영구)는 false로 변경됩니다. 도움 주셔서 감사합니다. – Greg

+1

멋진 답변, 새로운 것을 배웠습니다. 감사! –