#java #jpa #jakarta-ee #java-ee-7
#java #jpa #джакарта-ee #java-ee-7
Вопрос:
У меня есть @Stateless
-Bean, который выполняет некоторые операции с базой данных одним методом
public void doOperation(){
User u1 = createNewUser()
User u2 = createNewUser()
User updated = mergeUser(u1,u2) // just as an example
// should write to database now!
otherBlockingOperation()
}
Однако изменения не видны в базе данных до завершения операции блокировки и, следовательно, не видны во внешнем интерфейсе.
Я думал, это потому, что транзакция не зафиксирована до otherBlockingOperation()
завершения. Затем я завернул otherBlockingOperation()
в поток, который снова не сработал.
Однако я думаю, что реальная проблема заключается в том, merge
что обновит объект только после завершения метода. Как я могу мгновенно изменить значения объекта?
Редактировать:
@PersistanceContext
private EntityManager em;
mergeUser(T entity){
em.merge(entity);
em.flush();
}
Комментарии:
1. Пожалуйста, предоставьте код
mergeUser
, это может иметь отношение к делу. Вы правы в своем наблюдении о транзакциях: в@Stateless
компоненте транзакция запускается (по умолчанию), а база данных обновляется только после фиксации транзакции. Даже если выentityManager.flush()
во время транзакции обновите базу данных, но все равно изменения будут видны только в вашей транзакции (если не используется какой-либо нестандартный уровень изоляции)2. Кроме того, управление вашими собственными потоками в приложении JavaEE является основным «нет-нет». Сервер приложений должен быть единственным ответственным за обработку потоков, используя методологию JavaEE (т. е.
@Asynchronous
бизнес-методы и т.д.)
Ответ №1:
В зависимости от реальных бизнес-требований возможным решением было бы переместить otherBlockingOperation()
метод в новый @Stateless
компонент и пометить метод как @Asynchronous @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
. Это позволит эффективно запустить метод в новом потоке и новой транзакции. Вы бы просто @Inject
создали новый компонент и вызвали otherBlockingOperation()
метод.
Новая транзакция может быть (или не может быть) допустимой опцией, в зависимости от потребностей бизнеса (т. Е. Новая транзакция может завершиться неудачей, в то время как исходная транзакция может завершиться успешно). Однако обновление будет зафиксировано в базе данных раньше (но все равно после фиксации исходной транзакции) без зависимости от otherBlockingOperation()
процесса (или даже успешной фиксации).