Java ObjectOptimisticLockingFailureException和RollbackException

Java ObjectOptimisticLockingFailureException和RollbackException,java,hibernate,jpa,Java,Hibernate,Jpa,我对hibernate和jpa有问题 我有一个定期调用的方法,用于从数据库中的表中检索数据并将其发送到另一台服务器 以下是该方法的代码: protected List<MessagingMessage> getNewMessages() throws NoMessageAvailableException { return messagingPublisher.getNewMessages(application); } 如果出现ObjectOptimisticLockin

我对hibernate和jpa有问题

我有一个定期调用的方法,用于从数据库中的表中检索数据并将其发送到另一台服务器

以下是该方法的代码:

protected List<MessagingMessage> getNewMessages() throws NoMessageAvailableException {
    return messagingPublisher.getNewMessages(application);
}
如果出现ObjectOptimisticLockingFailureException,则事务将标记为rollbackonly。因此,我试图告诉事务不要为此异常回滚(通过注释),但它不起作用

你知道它为什么不起作用吗


谢谢。

发生此问题的原因很可能是
getNewMessages
调用了一些事务性方法,并且事务管理器的属性
globalRollbackOnParticipationFailure
设置为
true
(默认设置)

以下是相关的一部分:

设置是否将现有事务全局标记为仅回滚
参与交易失败后。
默认值为“真”:如果参与交易(例如
传播\需要或传播\支持遇到现有
事务)失败,事务将全局标记为仅回滚。
这种事务的唯一可能结果是回滚:
事务发起人无法再使事务提交。
将此选项切换为“false”,让事务发起人进行回滚
决定。如果参与事务因异常而失败,则调用方
仍然可以决定继续使用事务中的其他路径。
但是,请注意,只有在所有参与资源
即使在数据访问之后也能够继续进行事务提交
失败:例如,Hibernate会话通常不是这种情况;
对于一系列JDBC插入/更新/删除操作,它也不适用。
您已在外部事务上设置了
norollboor
,但

  • getNewMessages
    从不抛出
    ObjectOptimisticLockingFailureException
  • 更重要的是,只有当其他方法(我猜
    deleteGpsDataToSend
    @Transactional
    注释)抛出该异常时,事务才会标记为回滚
  • @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;
    }
    
    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
    
     Set whether to globally mark an existing transaction as rollback-only
     after a participating transaction failed.
     <p>Default is "true": If a participating transaction (e.g. with
     PROPAGATION_REQUIRES or PROPAGATION_SUPPORTS encountering an existing
     transaction) fails, the transaction will be globally marked as rollback-only.
     The only possible outcome of such a transaction is a rollback: The
     transaction originator <i>cannot</i> make the transaction commit anymore.
     <p>Switch this to "false" to let the transaction originator make the rollback
     decision. If a participating transaction fails with an exception, the caller
     can still decide to continue with a different path within the transaction.
     However, note that this will only work as long as all participating resources
     are capable of continuing towards a transaction commit even after a data access
     failure: This is generally not the case for a Hibernate Session, for example;
     neither is it for a sequence of JDBC insert/update/delete operations.