2010-08-16 75 views
2

在我的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爲定時器方法沒有死鎖發生。但爲什麼?異步方法調用什麼?

回答

0

讀鎖等待寫鎖來完成他們開始他們的工作之前。當timer()工作時,所有其他調用(即使是讀取方法)都將等待。你確定超時發生在result.get(4, TimeUnit.MINUTES);

我想你可能是在測試訪問超時()invokation,達到result.get(4, TimeUnit.MINUTES);之前的方式。

相關問題