开发者

DEADLOCK, EJB 3.1 with asynchronous Method and TimerService in Singleton

开发者 https://www.devze.com 2023-01-11 22:47 出处:网络
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 me

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)
开发者_JS百科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?


READ locks have to wait for WRITE locks to finish before they start their work. When timer() is working all your other invokations, even to READ methods, are going to wait. Are you sure the timeout happens in result.get(4, TimeUnit.MINUTES);?

I think you may be have access timeouts in test() invokation, way before reaching result.get(4, TimeUnit.MINUTES);.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号