У меня проблема с hibernate и jpa.
У меня есть метод, который регулярно вызывается для получения данных из таблицы в базе данных и отправки их на другой сервер.
Вот код метода:
protected List<MessagingMessage> getNewMessages() throws NoMessageAvailableException {
return messagingPublisher.getNewMessages(application);
}
Вот код от издателя:
@Override
@Transactional(noRollbackFor = {ObjectOptimisticLockingFailureException.class})
public List<MessagingMessage> getNewMessages(String application) throws NoMessageAvailableException {
List<GpsDataToSend> allGpsDatas = gpsDataToSendService.findByapplicationIgnoreCase(application);
List<MessagingMessage> allMessages = new ArrayList<>();
for (GpsDataToSend gpsDataToSend : allGpsDatas) {
MessagingMessage message = convertToMessagingMessage(gpsDataToSend);
// Ajout dans les messages à envoyer au TMS
allMessages.add(message);
try {
// Suppression des données de la base
gpsDataToSendService.deleteGpsDataToSend(gpsDataToSend.getId());
} catch (ObjectOptimisticLockingFailureException oolfa) {
// Si l'exception est levée, c'est que la donnée a été supprimée, donc déjà été envoyée au TMS
allMessages.remove(message);
Long idGpsDataToSend = ((GpsDataToSend) message.getObject()).getId();
log.info("The GPS message was already sent because the data doesn't exists anymore in database (id : {})", idGpsDataToSend);
}
}
return allMessages;
}
Издатель извлекает данные, преобразует их в сообщение, и данные удаляются из базы данных, чтобы быть уверенными, что они отправляются только один раз.
Проблема заключается в том, что у меня есть 2 сервера с балансировкой нагрузки, выполняющих один и тот же код, поэтому потенциально 2 сервера извлекают одни и те же данные одновременно. Иногда при удалении у меня возникало исключение ObjectOptimisticLockingFailureException, сообщающее, что данные для удаления отсутствуют.
Я обработал это исключение, чтобы убедиться, что оно не мешает остальной части исполнения.
Но теперь, когда возникает исключение ObjectOptimisticLockingFailureException, при следующем выполнении:
protected List<MessagingMessage> getNewMessages() throws NoMessageAvailableException {
return messagingPublisher.getNewMessages(application);
}
Я получаю это исключение:
2018-04-24 15:58:09 ERROR [pool-3-thread-1] c.g.m.m.w.WepSphereMqQueuePusher [WepSphereMqQueuePusher.java:76] Error getting new message to send org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526) ~[spring-orm-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at com.sun.proxy.$Proxy75.getNewMessages(Unknown Source) ~[na:na]
at com.geodisbm.mobility.messaging.websphere.WepSphereMqQueuePusher.getNewMessages(WepSphereMqQueuePusher.java:101) [messaging-1.0-SNAPSHOT.jar:na]
at com.geodisbm.mobility.messaging.websphere.WepSphereMqQueuePusher.sendAllMessages(WepSphereMqQueuePusher.java:71) [messaging-1.0-SNAPSHOT.jar:na]
at com.geodisbm.mobility.messaging.websphere.WepSphereMqQueuePusher.access$000(WepSphereMqQueuePusher.java:16) [messaging-1.0-SNAPSHOT.jar:na]
at com.geodisbm.mobility.messaging.websphere.WepSphereMqQueuePusher$1.run(WepSphereMqQueuePusher.java:63) [messaging-1.0-SNAPSHOT.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_45]
at java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:308) [na:1.8.0_45]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java) [na:1.8.0_45]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_45]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
Caused by: javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:58) ~[hibernate-entitymanager-5.1.12.Final.jar:5.1.12.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-4.3.14.RELEASE.jar:4.3.14.RELEASE]
... 20 common frames omitted
Похоже, что если возникает исключение ObjectOptimisticLockingFailureException, транзакция помечается как откатная. Поэтому я попытался сказать, что транзакция не откатывается для этого исключения (с помощью аннотации), но она не работает.
У вас есть идеи, почему это не работает?
Спасибо.