2016-07-27 106 views
1

我不確定在哪裏打開我的Transaction對象。在服務層內?還是控制器層?Java:如何在一個請求中處理多個Hibernate事務?

我的Controller基本上有兩個服務,我們稱它們爲AServiceBService。然後,我的代碼都類似:

public class Controller { 
    public AService aService = new AService(); 
    public BService bService = new BService(); 

    public void doSomething(SomeData data) { 
     //Transaction transaction = HibernateUtil.getSession().openTransaction(); 
     if (data.getSomeCondition()) { 
      aService.save(data.getSomeVar1()); 
      bService.save(data.getSomeVar2()); 
     } 
     else { 
      bService.save(data.getSomeVar2()); 
     } 


     //transaction.commit(); or optional try-catch with rollback 
    } 
} 

我想要的行爲是,如果bService#save失敗了,那麼我可以調用transaction#rollback所以,無論保存在aService將被回滾以及。這似乎是可能的,如果我爲這兩個保存創建一個單一的事務。

但從另一個角度來看,它看起來非常難看,我的Controller依賴於Transaction。如果我在相應的服務中創建Transaction會更好,(如Spring @Transactional的工作原理),但如果我這樣做,那麼我不知道如何實現我想要實現的目標......

編輯:固定代碼,增加了另一個條件。我沒有使用任何Spring依賴關係,所以@Transactional的使用是不可能的。

回答

3

你可以用另一個抽象層和使用合成來完成你所要求的。

public class CompositeABService { 
    @Autowired 
    private AService aservice; 
    @Autowired 
    private BService bservice; 

    @Transactional 
    public void save(Object value1, Object value2) { 
    aservice.save(value1); 
    bservice.save(value2); 
    } 
} 

public class AService { 
    @Transactional 
    public void save(Object value) { 
    // joins an existing transaction if one exists, creates a new one otherwise. 
    } 
} 

public class BService { 
    @Transactional 
    public void save(Object value) { 
    // joins an existing transaction if one exists, creates a new one otherwise. 
    } 
} 

此相同的圖案通常用於當需要使用多個存儲庫作爲工作(例如交易)的單一單元的一部分進行交互。

現在你所有的控制器需要依賴的是CompositeABService或任何你想命名它。

+0

好的 - 可能會有些偏離主題,但我沒有使用任何Spring依賴關係,所以我只是手動創建新的事務。如果我在CompositeABService.save()中打開一個事務 - 這意味着在AService.save()和BService.save()中打開另一個事務會導致錯誤。請看看我的編輯 – mpmp