2011-07-12 91 views
2

我們有一個基於Spring的應用程序,帶有@Transactional註解的服務層。我們需要之前和之後,原因如下一些事務方法有代碼的運行:在@Transactional方法之前和之後執行代碼

  1. 我們需要同步訪問基於密鑰的方法。該線程需要在事務開始之前阻塞。
  2. 如果事務成功,我們需要在隊列上發佈消息。

的選項似乎是:

  1. 創建類似的方法,可以在同步塊運行@Transactional方法和檢查返回然後發佈消息的服務類(需要由於AOP代理問題導致的單獨課程)。服務呼叫服務,不好,感覺像一個解決辦法。
  2. 編寫一個方面來環繞可以執行同步和消息發佈的@Transactional AOP。可能會工作,但寧願避免AOP。
  3. 將事務下移到域圖層。由於領域方法在不同的工作流程中被重複使用的方式,因此當前的實現不太可取或可能甚至是可行的。
  4. 在服務方法中手工編寫交易並廢止@Transactional。

我想這是一個相當普遍的要求。可能我錯過了一個選項5,這是顯而易見的選項!

回答

1

我會使用TransactionTemplate(您的選項4),並在這種情況下以編程方式控制事務的範圍。否則,您可以將您的方法中的邏輯移出到單獨的服務中,創建新的服務@Transactional,從當前的方法中移除@Transactional,然後用您的前置和後置環繞呼叫到新服務事務後邏輯。我也採取了這種方法,但我更喜歡programmatic transaction management這樣的要求,因爲我認爲它更清潔,並且正如你所提到的,服務調用服務(這只是第一個服務所需要的),就像是一個駭人的解決方法。

3

我想我會和2一起去,除非你有一些特定的理由來避免AOP。你的問題是AOP可以使用的典型例子,它的結果看起來不錯。這裏有一個很好的例子來說明如何實現(如果你沒有閱讀過):Advising transactional operations

如果AOP真的不是一個選項,我會選擇@Lawrence McAlpin提出的'其他'選項。

+0

同意這一點,我不明白爲什麼人們會想在這種情況下避免AOP。這是最乾淨的方法。 –

+1

這是要走的路,畢竟@Transactional也使用AOP。所以連接另一個方面將是最好和最簡單的事情。 –

+2

絕對使用AOP。正如@Sean指出的那樣,您已經在使用@Transactional來使用Spring AOP,並且Spring特別支持[定位註釋的切入點表達式](http://static.springsource.org/spring/docs/3.1.x/spring-framework -reference/html/aop.html#aop-pointcuts-designators),所以你可以告訴它在沒有額外工作的情況下每個@Transactional方法運行。 –

2

退房TransactionSynchronization回調界面。 Spring可以自然地告訴你事務發生了什麼。

+0

Tomasz對郵件發佈要求非常有用,謝謝。其實這可能是我們也遇到的其他一些長期問題的解決方案,這非常棒。 –

0

如果鍵被作爲方法調用的一部分傳遞,那麼你可以使用Java ReentrantLock做的工作..其簡單得多&清潔。

相關問題