DEADLOCK, EJB 3.1 с асинхронным методом и TimerService в синглтоне - PullRequest
2 голосов
/ 16 августа 2010

В моем Singleton-EJB я запускаю TimerService каждые 2 минуты.Когда клиент обращается к тестовому методу, приложение иногда заходит в тупик.Проблема заключается в том, что метод test вызывает асинхронный метод внутри EJB (см. Метод defineABC ).Блокировка возникает, когда scheduleMethod пытается создать таймер одиночного действия и, следовательно, пытается получить блокировку (поскольку метод обратного вызова таймера аннотирован с помощью LOCK.WRITE).В то же время мы уже используем метод define ABC , который пытается вызвать асинхронный метод asynchMethod .Возможно, вызов ejbLocal.asynchMethod (...); также пытается получить блокировку.В любом случае, здесь я захожу в тупик, потому что асинхронный метод никогда не вызывается.Так в чем же проблема?

Вот фрагмент исходного кода:

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

Тупик также возникает, когда я использую только метод @ Schedule и не TimerService ... DeadLock также происходит, когда я не использую объект Future, но теряю силу в качестве возвращаемого типа асинхронного метода.

Когда выбрасывается исключение тайм-аута, тупик решается.Когда я аннотирую метод timer с помощью @ AccessTimeout (2000) , и это время истекло, вызывается асинхронный метод, и поэтому тупик также решается.

Когда я использую Locktype.READ для таймера Метод без тупиков.Но почему?Что вызывает асинхронный метод?

1 Ответ

0 голосов
/ 07 ноября 2014

Блокировки READ должны ждать окончания блокировки WRITE, прежде чем они начнут свою работу.Когда timer () работает, все остальные вызовы, даже для методов READ, будут ждать.Вы уверены, что тайм-аут произошел в result.get(4, TimeUnit.MINUTES);?

Я думаю, у вас может быть тайм-аут доступа при вызове test (), задолго до достижения result.get(4, TimeUnit.MINUTES);.

...