views:

130

answers:

0

In my Singleton-EJB i start a TimerService every 2 minutes. When a client access the test method sometimes the application runs into a deadlock. The problem is, the test method calls a asynchronous method inside the EJB (see Method determineABC). The deadlock happens when the scheduleMethod tries to create a single action timer and therefore tries to acquire a lock (because hte timer callback method is annotated with LOCK.WRITE). At the same time we are already in the determineABC Method which tries to invoke the asynchronous method asynchMethod. Maybe the call of ejbLocal.asynchMethod(...); also tries to acquire a lock. Anyway here i run into a deadlock, because the asynchronous method is never called. So what is the problem?

Here is a source code snippet:

@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);
}

The Deadlock also happens when i only use the @Schedule Method and no TimerService... The DeadLock also happens when i do not use a Future Object but void as return type of the asynchronous Method.

When the timeout Exception is thrown the deadlock is solved. When i annotate the timer method with @AccessTimeout(2000) and this time is up the asynchronous method is called and therefore the deadlock is also solved.

When i use Locktype.READ for the timer Method no Deadlock happens. But why? What does the asychronous method call?