2015-11-24 1 views
0

У меня есть сессионный компонент без состояния. В следующем методе я зацикливаю список, чтобы вставить каждого пользователя в таблицу «пользователь».EJB Container Управляемая транзакция с набором результатов JDBC и MDB

void saveUserList(List<User> users) { 
    try { 
    conn = dataSource.getConnection(); 
    PreparedStatement ps; 

    try { 
     ps = conn.prepareStatement(INSERT_USER_LIST); 

     for (User user : users) { 
     ps.setString(1, user.getName); 

     if (ps.executeUpdate() > 0) { 
      sendJMSMessage(); 
     } 
     } 
    } 
    } catch (SQLException e) { 
    // catch error!! 
    } finally { 
    closeResource(conn); 
    } 
} 

После каждой успешной вставки флаг триггера отправляется в MDB. Вот метод sendJMSMessage ...

void sendJMSMessage() { 
    conn = connectionFactory.createQueueConnection(); 
    qsession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 
    QueueSender sender = qsession.createSender(queue); 
    conn.start(); 

    TextMessage flag = qsession.createTextMessage("triggerFlag"); 
    flag.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT); 
    sender.send(flag); 
} 

Тогда он будет вызывать метод OnMessage ПДБ в. Здесь, в onMessage, я хочу получить всех пользователей из таблицы «пользователь», включая последнего вставленного пользователя (который еще не завершен, когда цикл все еще повторяет список). Процесс выборки произошел в другом EJB без сохранения состояния, который вызывается функцией onMessage. Я ожидал, что запись будет найдена там. Но наборы результатов ничего не получили.

void onMessage(Message message) { 
    TextMessage obj = (TextMessage) message; 

    if (obj.getText.equals("triggerFlag")) { 
    ArrayList<User> users = someBean.getUsers(); 
    // Do something with them, as well as the new user. 
    } 
} 

С текущего кода, я обычно необходимо повторно выполнить saveUserList() с переходом другой список, чтобы получить ожидаемый результат. Я хотел бы знать:

  1. Возможно ли это?
  2. Когда выполняется первая транзакция вставки?
  3. Может ли MDB читать неуместные изменения в таблице?
  4. Каков правильный способ чтения изменений таблицы из MDB, который был инициирован EJB?
  5. Есть ли альтернативный метод для этого?

ответ

1
  1. Да, это возможно.
  2. Это действительно зависит от того, как вы получили соединение (или DataSource). Если вы развернули его из введенного EntityManager, транзакция автоматически будет совершена, если ваш (первый введенный) EJB-метод вернется (это по умолчанию, то есть, если ничего не аннотируется!)
  3. Да, если соединение MDB использует самую низкую уровень изоляции транзакций «READ_UNCOMMITTED». Это не тривиально реализовать и снова зависит от того, как вы получаете соединение.
  4. (& 5) Возможно, самый чистый способ решить вашу проблему - управлять транзакцией вручную (используйте введенный UserTransaction вместо транзакций, управляемых контейнерами (CMT)). Только вы закончите, если весь список пользователей (а не для каждого пользователя, как сейчас), и после того, как вы совершили транзакцию (с программным обеспечением UserTransaction), вы на 100% уверены, что ваш второй компонент без состояния будет видеть всех ваших пользователей. В этом случае вы должны отправить сообщение только один раз.
+0

«Если вы развернули его из инъецируемого EntityManager». Что это значит? – Bogie

+0

http://stackoverflow.com/questions/16994226/how-to-get-datasource-or-connection-from-jpa2-entitymanager-in-java-ee-6 –

+0

В моем случае я просто смотрю на источник данных JNDI с InitialContext. Что делать, если я создаю новую транзакцию в методе onMessage (с UserTransaction.begin())? Будет ли зафиксирована предыдущая транзакция (которая происходит в первом EJB)? – Bogie

Смежные вопросы