Как сохранить объект в отдельном потоке с помощью JPA на сервере приложений J2EE?

#multithreading #jpa #concurrency #jakarta-ee

#многопоточность #jpa #параллелизм #джакарта-ee

Вопрос:

У меня есть приложение для чата, которому необходимо сохранять сообщения в БД. Но соединение с базой данных происходит немного медленно, поэтому это задерживает ответ клиенту чата.

Возможно ли сохранить объект сообщения в отдельном потоке? Что мне на самом деле нужно: уменьшить задержку перед отправкой-получением сообщения на клиенте.

Я пытаюсь это сделать, но это не работает.

Объект Dao:

 @Stateless
public class MessagesDAO {
    @PersistenceContext(type= PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    private PersistenceThread persistenceThread = new PersistenceThread();

    //another methods

    public void addMessage(Message message) {
        Thread thread = new Thread(persistenceThread);
        persistenceThread.setMessage(message);
        thread.start();
    }

    private class PersistenceThread implements Runnable {
        private Message message;

        public void setMessage(Message message) {
            this.message = message;
        }

        public void run() {
            entityManager.persist(message);
        }
    }
}
  

Интерфейсная служба, которая вызывает DAO для сохранения нового сообщения, а затем возвращает его клиентам:

 @Stateless
@Path("/messages")
@Produces("application/xml")
@Consumes("application/xml")
public class MessagesServiceImpl {
    @EJB
    private MessagesDAO messagesDAO;

    @POST
    @Broadcast(resumeOnBroadcast = true)
    public Message postMessage(Message message) {
        messagesDAO.addMessage(message);
        return message;
    }

    @GET
    @Path("/wait")
    @Suspend(outputComments = false)
    public Message waitForLastMessage() {
        return null;
    }
    //another methods

}
  

Спасибо.

Ответ №1:

Попробуйте аннотацию @Asynchronous:

 @Stateless
public class MessagesDAO {

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;

    @Asynchronous
    public void addMessage(Message message) {
      entityManager.persist(message);
    }
}
  

Просто имейте в виду, что для этого требуется EJB 3.1.