2016-10-18 28 views
0

我有一個無狀態bean,它使用其他bean(本地注入)的異步方法插入一些數據。這個數據插入需要一些時間,所以我不等待完成這個操作。在這個數據插入之後,我調用了同一個bean的另一個方法。當我將一個調試點放到方法中時,服務器等待大約90秒才能達到此點。可能是Jboss等待事務完成異步方法。我不知道發生了什麼事。 。JBOSS EAP 6在異步方法之後被阻塞來調用ejb方法

@Stateless 
public class SimulationNodePersistenceBean implements SimulationNodePersistenceRemote, SimulationNodePersistenceLocal { 
    @Resource 
    SessionContext context; 

    @EJB 
    private SimulationResultGraphPersitenceBean graphPersistenceBean; 

    @Asynchronous 
    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    private void addResultGraphsToDatabase(long id, Graph[] graphList) { 

    ResultGraph paramGraph; 
    ResultGraphPoint dataPoint; 
    Graph graph; 
    for (int i = 0; i < graphList.length; i++) { 
     graph = graphList[i]; 
     paramGraph = new ResultGraph(); 

     try { 
      graphPersistenceBean.persistGraph(paramGraph); 
     } catch (Exception databaseException) { 
      // TODO add error message to the contingency simulation messages 
      // list 
      logger.error("Error saving ResultGraph:" + paramGraph); 
     } 
    } 
    long duration = System.nanoTime() - startTime; 
    logger.debug("Graphs inserted to DB in (sec) :" + (duration/NANO_SECOND_CONVERSION_FACTOR)); 
} 

    // @Asynchronous 
public void persistSimulationResults(long contingencySimulationId, Graph[] graphList, 
     List<AB> reiList) { 
    if (graphList != null) { 
     addResultGraphsToDatabase(contingencySimulationId, graphList); 
    } 
    if (reiList != null) { 
    //another method 
    } 
    calculateContSimStability(contingencySimulationId); 
} 

    @Override 
public void calculateSimIndex(long id) { 

} 

這是主要的綠豆

@Stateless 
public class SimulationResultGraphPersitenceBean { 
    @PersistenceContext(unitName = "DBService") 
    private EntityManager em; 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    @Asynchronous 
    public void persistGraph(ResultGraph graph) throws SiGuardPersistenceException { 
     try { 
      ResultGraphService service = new ResultGraphService(em); 
      service.create(graph); 
      em.flush(); 
     } catch (Exception ex) { 
      throw new PersistenceException("Error persisting graph", ex); 
     } 
    } 

叫其他的bean這是客戶端調用主bean.This以異步方式工作。

getSimulationEJB().persistSimulationResults(id, tsaParser.getLstFile().getGraphArray()); 

調用此方法後,我調用SimulationNodePersistenceBean的另一個方法。此方法等待幾分鐘。

getSimulationEJB().calculateSimIndex(contSimId); 

我已經使用jstack創建了一個線程轉儲。其實我在Jboss As 6中沒有這個問題。我將我的應用程序遷移到了Jboss EAP 6. 4.可能需要對配置進行一些配置更改。但我不知道該怎麼辦。

我檢查了線程轉儲。我在BLOCKING狀態下找不到任何線程。我應該尋找其他關鍵字嗎?

+0

如果您可以提供一些示例代碼(或僞代碼)來說明您的問題,那麼很容易理解。 –

+0

我通過添加代碼編輯 – user725455

+0

我看不到調用addResultGraphsToDatabase()方法。我的猜測是你從persistSimulationResults()調用它。 在此之前,請確保它確實異步調用(因爲您正在混合異步和同步方法)。你應該記得從sessionContext中調用異步方法。我只是想確定你沒有犯這種常見的錯誤。請看這裏:https://satishgopal.wordpress.com/2011/04/24/ejb-3-1-asynchronous-methods/(看看「混合同步和異步」段落)。讓我知道。 –

回答

1

正如我在評論中已經指出的那樣,您正在混合調用異步和同步方法。在你的例子中,你從persistSimulationResults方法(這是一個同步方法 - 因爲你註釋掉了它的異步註釋)調用addResultGraphsToDatabase方法(這是一個異步方法)。因此,儘管有異步註釋,但現在addResultGraphsToDatabase方法的行爲與同步方法類似。

我不確定你是否看過我在評論中發佈的鏈接,但需要使用SessionContext調用Asynch方法。事情是這樣的:

在類級別:

@Inject 
SessionContext ctx; 

的,在persistSimulationResults方法中:

ctx.addResultGraphsToDatabase 

對於更詳細的例子,請看看我已經發布的鏈接在評論中。

+0

感謝您的回覆。我是否也應該將persistSimulationResult方法定義爲異步方法?因爲從裏面調用的其他方法不應該異步工作 – user725455

+0

我試圖調用addResultGraphsToDatabase方法使用\t \t \t context.getBusinessObject(SimulationNodePersistenceBean.class).addResultGraphsToDatabase(contingencySimulationId,graphList);.它拋出非法狀態異常 – user725455

+0

請發佈stacktrace的前幾行,以便我能夠幫助你。 –