2015-10-19 27 views
0

我想出來的@Transactional註釋,但我不知道這正是錯誤的,我有以下的代碼@Transactional不工作就扔一個RuntimeException

控制器

@RequestMapping(value = "/remove", method = RequestMethod.POST) void removeUserFlight(@RequestParam("flightId") Long flightId) throws Exception { 
    int affectedRows = userFlightDao.removeFlightByFlightId(flightId, user.getId()); 
    throw new RuntimeException("Testing rollback?"); 
} 

@Repository 
public interface UserFlightDao extends CrudRepository<UserFlight, Long> { 
    /** Named DELETE query defined in {@link UserFlight} */ 
    @Modifying @Transactional int removeFlightByFlightId(Long flightId, Long userId); 
} 

我的印象是,如果在執行行後拋出異常,記錄不會被刪除。有誰能澄清這裏有什麼問題嗎?

編輯:我也試着把@Transactional放在控制器的方法上,但沒有任何區別。

edit2:試圖將邏輯移動到下面的Ralph建議的服務,它工作正常。我仍然不知道爲什麼控制器方法上的@Transactional直接不起作用。我會認爲現在解決了這個問題,但我仍然感到困惑。

+0

您是否試過將'@ Transactional'放在控制器上並在DAO中刪除它? – Chaitanya

+3

您在提交事務後拋出異常,應該如何回滾任何事物。 –

+1

參見上面的@ M.Deinum評論。總的來說,將跨國行爲移動到更高抽象級別(服務)上是一個不錯的主意,這樣您就可以從各自具有自己事務邏輯的各種服務中使用相同的存儲庫方法(例如,將多個存儲庫合併爲一個服務方法,沒問題)。 –

回答

2

您必須在事務中拋出異常。 (如果在事務已經提交之後拋出異常,那麼它保持提交)。

默認情況下,事務在離開已啓動的方法時被執行。

對於您的Testcase:添加一個帶有事務註釋的中間服務,然後在該服務方法中拋出異常。

@Service 
public class IntermediateService() { 
    @Autowired 
    UserFlightDao userFlightDao; 

    @Transactional //maybe try propagation Requires_new 
    public void doMyTest() { 
     userFlightDao.removeFlightByFlightId(...); 
     throw new RuntimeException("Testing rollback?"); 
    } 
} 
+0

謝謝,但你能解釋直接控制器方法內的removeFlightByFlightId調用和服務方法之間的區別?他們兩個都在通話結束後拋出異常,不是? – prettyvoid

+1

您的控制器方法不是事務性的,服務方法是。在交易開始和結束的地方的主要區別.. –

+0

我試着用'@ Transactional'註釋控制器方法,但我得到了相同的行爲。 – prettyvoid

相關問題