在我的Singleton-EJB中,我每2分鐘啓動一個TimerService。當客戶端訪問測試方法 有時應用程序會陷入死鎖。問題是,該測試方法調用EJB(參見方法determineABC)內的異步方法。當scheduleMethod嘗試創建單個操作計時器並因此嘗試獲取鎖(因爲hte timer回調方法用LOCK.WRITE註釋)時發生死鎖。同時,我們已經在嘗試調用asynchMethod異步方法determineABC方法。也許電話ejbLocal.asynchMethod(...);也試圖獲得一個鎖。無論如何,我遇到了一個死鎖,因爲異步方法從來沒有被調用過。那麼問題是什麼?DEADLOCK,具有異步方法的EJB 3.1和Singleton中的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);
}
死鎖也發生在我只用@Schedule方法,沒有TimerService ... 僵局也發生在我不使用Future對象,但是作爲異步方法的返回類型無效。
當超時異常被拋出的僵局得到解決。當我註釋計時器方法與@AccessTimeout(2000)和這個時間已到的異步方法被調用,因此,死鎖也得到解決。
當我使用Locktype.READ爲定時器方法沒有死鎖發生。但爲什麼?異步方法調用什麼?