2014-12-06 63 views
0

我有一個jUnit測試,我測試我的實體 - 一個音樂家必須具有唯一的名稱,我正在檢查它是否被數據庫按預期拒絕。我決定手動管理我在Spring中的事務,以更好地理解正在發生的事情,而不是使用@Transactional方法。我已經閱讀了PlatformTransactionManager的rollback()方法的文檔,當commit()拋出一個錯誤時,我不能在txManager上執行rollback(),因爲commit()已經回退了這個事務。鏈接就是here。但是當我不調用這個rollback()方法時,數據庫進入非法狀態並且整個模式被破壞並且測試停止。當我添加一個IF來確保tx沒有完成並且一次調用rollback()方法時,一切正常。這裏是代碼:當一個commit()在Spring編程事務中拋出一個異常時,我是否需要調用rollback()方法?

@Test 
public void testAddMusicianWithNotUniqueName() throws Exception { 
    System.out.println("addMusicianWithNotUniqueName"); 
    Musician musician1 = new Musician(); 
    musician1.setName("Musician 1"); 
    Musician musician2 = new Musician(); 
    musician2.setName("Musician 1"); 

    TransactionStatus status = null; 
    try { 
     DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
     status = txManager.getTransaction(def); 
     musicianDao.addMusician(musician1); 
     musicianDao.addMusician(musician2); 
     txManager.commit(status); 
     fail("MusicianException was not thrown when musician's name was not unique"); 
    } catch (DataAccessException ex) { 
     //now I added this code, even if 
     //commit thrown error so it has already cleaned the transaction as said in documentation 
     if(!status.isCompleted()){ 
      //but it apparently didn't clean the transaction as it is still not completed 
      txManager.rollback(status); 
     } 
    } 
} 

你能解釋這個給我嗎?提前致謝。

回答

0

您尚未添加完整的代碼。但是,原因是您首先提交事務,然後通過JUnit測試失敗。交易將按照您的代碼進行。如果你不希望數據被提交不嘗試以下操作:

fail("MusicianException was not thrown when musician's name was not unique"); 
txManager.commit(status); 

這將引發java.lang.AssertionError,因此該交易將不被確認。

+0

謝謝,但我已經說過,提交拋出一個異常,所以失敗只是爲了確保提交拋出的錯誤。那麼,爲什麼然後我必須回滾,即使在文檔中它說你不應該手動回滾時提交拋出異常...你可以解釋這個給我嗎? – Xenon 2014-12-18 22:46:59

+0

這是因爲您使用的是編程事務,而不是容器管理器事務。預計你會回滾。 – 2014-12-24 17:00:00

相關問題