2016-10-18 10 views
0

У меня есть компонент без состояния, который вставляет некоторые данные, используя асинхронный метод другого компонента (локальная инъекция). Эта вставка данных занимает некоторое время, поэтому я не жду окончания этой операции. После этой вставки данных я вызываю другой метод одного и того же компонента. Когда я помещаю точку отладки в метод, сервер ждет около 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.This работает асинхронно.

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

После вызова этого метода, я называю еще один метод, метод SimulationNodePersistenceBean.This ждет в течение нескольких минут.

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

Как уже указывалось в комментариях, вы смешиваете вызов асинхронных и синхронных методов. В вашем примере вы вызываете метод addResultGraphsToDatabase (который является методом Asynch) из метода persistSimulationResults (который является синхронизирующим методом - поскольку вы прокомментировали асинхронную аннотацию поверх него). Поэтому сейчас метод addResultGraphsToDatabase ведет себя как синхронный метод, несмотря на асинхронную аннотацию.

Я не уверен, посмотрел ли вы ссылку, которую я опубликовал в комментариях, но вам нужно вызвать метод Asynch, используя SessionContext. Что-то вроде этого:

На уровне класса:

@Inject 
SessionContext ctx; 

, в рамках метода persistSimulationResults:

ctx.addResultGraphsToDatabase 

Для более подробного примера, пожалуйста, посмотрите на ссылку я разместил в комментариях.

+0

Спасибо за ваш ответ. Должен ли я также определять метод persistSimulationResult как асинхронный метод?Поскольку другой метод, вызванный изнутри, не должен работать асинхронно – user725455

+0

Я попытался вызвать метод addResultGraphsToDatabase, используя \t \t \t context.getBusinessObject (SimulationNodePersistenceBean.class) .addResultGraphsToDatabase (contingencySimulationId, graphList) ;. Он выбрасывает недостоверное исключение – user725455

+0

Пожалуйста, разместите первые несколько строк stacktrace, чтобы я мог вам помочь. –