2011-11-08 110 views
21

我使用@Configuration註釋來配置spring,而不是xml文件。我使用不同的會話工廠和不同的事務管理器配置2個數據源。我在這裏爲@EnableTransactionManagement註解卡住了問題。我的文檔是,@EnableTransactionManagement帶2個事務管理器的註釋

@EnableTransactionManagement is more flexible; it will fall back to a by-type lookup for any PlatformTransactionManager bean in the container. Thus the name can be "txManager", "transactionManager", or "tm": it simply does not matter.

這意味着我給方法的任何名稱,它總是會尋找,而我有2個事務管理器返回PlatformTransactionManager對象的方法讀取。現在的問題是,當我測試這個類,它給我的錯誤:

org.springframework.beans.factory.NoSuchBeanDefinitionException : No unique bean of type [ org.springframework.transaction.PlatformTransactionManager ] is defined: expected single bean but found 2

我什至有2個不同的配置類,但徒勞無功。在xml配置中,情況並非如此。我給兩位交易經理註冊了兩個<tx:annotation-driven transaction-manager="" />標籤,它工作正常。但不能在這裏做註釋。

如果我想在Spring註釋的配置類中使用2個不同的事務管理器配置2個數據源,應該怎麼做?

+0

這可能是一個bug,因爲Spring 3.1仍處於beta/rc階段。 – skaffman

回答

5

java doc

For those that wish to establish a more direct relationship between
@EnableTransactionManagement and the exact transaction manager bean to be used, the TransactionManagementConfigurer callback interface may be implemented - notice the implements clause and the @Override -annotated method below:

@Configuration類需要實現TransactionManagementConfigurer接口 - 實現annotationDrivenTransactionManager將返回引用應使用的transactionManager

+0

我也讀過這個。但問題是,實現的方法調用transactionmanager方法並返回相同的事務管理器對象,而我想在我的配置類中有2個事務管理器。由於@EnableTransactionManagement沒有看到方法名稱,只是看看哪個是PlatformTransactionManagement對象,它不會允許2個事務管理器進行配置。 –

+0

只需從annotationDrivenTransactionManager方法 – gkamal

+0

返回您想要由@EnableTransactionManagement使用的引用即可。這就是問題所在。不能確定使用哪個事務管理器,因爲它取決於模型對象。我有來自2個不同數據庫的2個模型,但是它們都是同時完成的。現在,無論如何,數據不能插入到1個表中,其他條目也應該被丟棄,因此事務回滾可能發生在任何地方。 –

0

其他一些答案意味着使用兩個事務管理器在某種程度上是錯誤的;但是,Spring的XML配置允許使用多個事務管理器,如聯機文檔中所述(下文)。不幸的是,似乎沒有辦法使@EnableTransactionManagement註釋以類似的方式工作。因此,我只需使用@ImportResource註釋來加載包含<tx:annotation-driven/>行的XML文件。這使您可以獲得大多數情況下的Java配置,但仍然使用帶有可選事務管理器限定符的@Transactional

http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/transaction.html

Most Spring applications only need a single transaction manager, but there may be situations where you want multiple independent transaction managers in a single application. The value attribute of the @Transactional annotation can be used to optionally specify the identity of the PlatformTransactionManager to be used. This can either be the bean name or the qualifier value of the transaction manager bean. For example, using the qualifier notation, the following Java code

25

在您的配置類,使用@EnableTransactionManagement註解。

在這個類中定義一個事務管理器爲:

@Bean(name="txName") 
    public HibernateTransactionManager txName() throws IOException{ 
     HibernateTransactionManager txName= new HibernateTransactionManager(); 
     txName.setSessionFactory(...); 
     txName.setDataSource(...); 
     return txName; 
    } 

那裏,在你的類/方法的執行事務工作(S),註釋如下:

@Transactional("txName") 

@Transactional(value = "txName") 

這就是你如何將名字限定的事務管理器綁定到任何你需要它的地方。現在您可以擁有任意數量的事務管理器,並根據需要隨時使用它。

+0

太棒了!有用!! – jherranzm

+0

它爲我節省了幾個小時!謝謝 –

7

萬一有人運行到這個問題,我找到了一個解決方案:

@Configuration 
@EnableTransactionManagement 
@DependsOn("myTxManager") 
@ImportResource("classpath:applicationContext.xml") 
public class AppConfig implements TransactionManagementConfigurer { 

@Autowired 
private PlatformTransactionManager myTxManager; 

... 

@Override 
public PlatformTransactionManager annotationDrivenTransactionManager() { 
    return this.myTxManager; 
} 

通過這種方式,您可以使用XML配置定義的特定txManager。

如果你要定義的txManager服務級別時,你應刪除@Configuration@EnableTransactionManagement註釋,並在註釋@Transactional指定txManager,例如

@Service 
@Transactional(value="myTxManager", readOnly = true) 
public class MyServiceImpl implements MyService { ... } 
+0

它如何支持兩個事務管理器? – instanceOfObject

+0

您可以使用XML配置儘可能多的'txManager',您可以使用'@DependsOn()'或'@Transactional()'註釋在應用程序或服務級別上使用任何配置的'txManager'如上所述 – Sleeper9