2010-08-16 3 views
2

내 Singleton-EJB에서는 2 분마다 TimerService를 시작합니다. 클라이언트가 테스트 메소드 에 액세스 할 때 가끔 애플리케이션이 교착 상태가됩니다. 문제는 테스트 메서드가 EJB 내부에서 비동기 메서드를 호출한다는 것입니다 (방법 결정 ABC 참조). 교착 상태는 scheduleMethod이 단일 작업 타이머를 만들려고 시도하기 때문에 발생합니다 (hte 타이머 콜백 메서드에 LOCK.WRITE가 지정되어 있기 때문에). 동시에 우리는 이미 있습니다 결정 ABC 비동기 메서드를 호출하는 메서드 asynchMethod. 어쩌면 의 호출 ejbLocal.asynchMethod (...); 또한 잠금을 획득하려고 시도합니다. 어쨌든 여기서 비동기 메서드는 호출되지 않기 때문에 교착 상태가 발생합니다. 문제가 무엇입니까? 여기 DEADLOCK, EJB 3.1 (비동기 메서드 및 TimerService 포함)

는 소스 코드입니다 : 내가 사용하지 않는 경우 난 단지 @Schedule 방법도없고 TimerService을 ... 사용할 때

@Singleton 
@Startup 
@TransactionManagement(TransactionManagementType.CONTAINER) 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) 
public class XEJB implements XEJBLocal { 

@javax.annotation.Resource(name = "x/XEJB/TimeService") 
private TimerService timerService; 
@javax.annotation.Resource 
private SessionContext ctx; 

@Schedule(minute = "*/2", hour = "*", persistent = false) 
@Lock(LockType.READ) 
private void scheduleMethod() { 
    // Create Single Action Timer 
    timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false)); 
} 

@Timeout 
@Lock(LockType.WRITE) 
private void timer(Timer timer) { 
    // Do something 
} 

@Override 
@Lock(LockType.READ) 
public B test(...) { 
    return determineABC(...); 
} 

@Lock(LockType.READ) 
private B determineABC(...) { 
    XEJBLocal ejb= (XEJBLocal) ctx.getBusinessObject(ctx.getInvokedBusinessInterface()); 
    Future<ArrayList> result = null; 
    result = ejb.asynchMethod(...); 
    result.get(4, TimeUnit.MINUTES); // Sometimes runs into a DEADLOCK 
    ... 
} 

@Asynchronous 
@Override 
@Lock(LockType.READ) 
public Future<ArrayList> asynchMethod(...) { 
    ... 
    return new AsyncResult<ArrayList>(abcList); 
} 

교착 상태는 발생 교착 상태는 발생 미래 객체이지만 비동기 메소드의 반환 유형은 void입니다.

시간 초과 예외가 발생하면 교착 상태가 해결됩니다. 내가 타이머 메서드에 @AccessTimeout (2000)으로 주석을 달고이 시간이되면 비동기 메서드가 호출되므로 교착 상태도 해결됩니다.

타이머에 Locktype.READ를 사용할 때 메소드가 교착 상태가됩니다. 하지만 왜? 비동기식 방법은 무엇이라고 부릅니까?

답변

0

읽기 잠금은 WRITE 잠금이 작업을 시작하기 전에 완료 될 때까지 대기해야합니다. timer()가 작동 중일 때 다른 모든 호출 (심지어 READ 메소드까지)이 기다릴 것입니다. result.get(4, TimeUnit.MINUTES);에 시간 초과가 발생 했습니까?

나는 당신이 result.get(4, TimeUnit.MINUTES);에 도달하기 전에 test() 호출에서 액세스 제한 시간을 가질 수 있다고 생각합니다.