2016-06-15 48 views
2

我想忽略在彈簧CrudRepository的刪除操作中發生的任何異常。如果數據庫ID不再存在,如何忽略刪除異常?

@Tranactional 
public void remove(Long id) { 
    try { 
     if (id != null) dao.delete(id); //CrudRepository 
    } catch (Exception e) { 
     //ignore any exceptions, it's not critical delete 
    } 
} 

問題:當我運行這個,我還是收到以下異常(例如,如果要刪除的ID沒有在數據庫中存在了 - 意味着它可能已被刪除,同時)。我怎麼能忽略它?

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.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
+0

此異常沒有發生。您列出的代碼不會拋出您發佈的異常。 – EJP

+0

嗯,但日誌完全指向'dao.delete()'所在的代碼行。 – membersound

回答

-1
@Tranactional(rollbackFor={TableNotFoundException1.class, RecordNotFoundException.class} 
public void remove(Long id) { 
    try { 
     if (id != null) dao.delete(id); //CrudRepository 
    } catch (Exception1 e) { 
     throw new TableNotFoundException1(); 
    }catch (Exception2 e) { 
     throw new RecordNotFoundException(); 
    }catch (Exception e) { 
     throw new RecordNotFoundException(); 
    } 
} 

你必須要找到你是如何捕獲Exception1Exception2或只是使用ExceptionrollbackFor={Exception.class}

爲什麼需要申報rollbackFor?默認情況下,Spring只回滾未檢查的異常。

其他選項: 將繼也行,但不使用@Tranactional

//@Tranactional(rollbackFor={TableNotFoundException1.class, RecordNotFoundException.class} 
public void remove(Long id) { 
    try { 
     if (id != null) dao.delete(id); //CrudRepository 
    }catch (Exception e) { 
     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 
    } 
} 
+0

@andolsizied檢查春季文檔+ https://stackoverflow.com/questions/7125837/why-does-transaction-roll-back-on-runtimeexception-but-not-sqlexception/7125918#7125918 – sura2k

0

即使你捕獲異常,事務管理器將事務標記爲rollbackonly,所以當你提交的的結束方法,你將有一個TransactionSystemException異常。

們的第一反應是標記方法@Transactional(noRollbackFor=EmptyResultDataAccessException.class),而是因爲如果你把在SimpleJpaRepository類一看西港島線看到delete方法被標記爲transactional這並沒有解決問題,所以當異常被拋出,這@Transactional標誌着你事務僅作爲回滾。

我認爲,該解決方案是調用findOne方法,然後,如果實體存在呼叫delete方法(調用由實體而不是由ID刪除方法):刪除操作期間

@Tranactional 
public void remove(Long id) { 
    if (id != null) { 
    YouEntity entity= dao.findOne(id); 
    if (nonNull(entity)) { 
     dao.delete(entity); 
    } 
    } 
}