被忽略的Spring3小改進——支持多數據源的@Transactional事務註解

被忽略的Spring3小改進——支持多數據源的@Transactional事務註解

[問題]


近日,有同事問起,有個項目在配置Spring事務時,使用了@Transactional註解,但這個項目使用了多個數據源,而事務註解只對第一個起作用,咋辦?

 

[探幽]

一聽之下,想起在用@Transactional配置事務時,確實沒注意過多數據源問題,但是記得之前常用的XML配置方式中,對多數據源支持很簡單,我想註解配置起來應該也不會太麻煩。

 

先回顧一下之前個人習慣使用的 <tx:advice> + <aop:config>配置方式,大致步驟如下:
1)定義與事務管理器對應的事務通知
2)配置需要攔截的方法調用切面
3)將切入點連接到相應的事務通知
整個系統的事務,三下配置,一處搞定,相比註解方式,個人覺得更簡單、省力、統一;而要支持多數據源,再做一遍這123即可,非常簡單。

 

不過同事在網上百度了一圈,說大部分的結論是Spring的@Transactional註解不支持,聽到這一點我很詫異,不應該啊,要不查查Spring的官方文檔?

一查馬上發現,在Spring3.0的參考文檔中,針對這個問題的,真新增了一節(10.5.6.2)來解決,參見:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations

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

 

也就是說,在Spring2.5之前,@Transactional註解確實不支持多數據源,但是Spring3爲其增加了value屬性配置,可以指定當前事務通知對應的事務管理器。

 

檢查了一下Spring的changelogs,這個特性是在3.0M4版中加入的:
@Transactional supports qualifier value for choosing between multiple transaction managers

[解難]


看來,或許這是一個有用的小改進,但很可能被大家忽略了。下面是從官方文檔中摘抄出來的示例配置方式,供需要的同學參考:

1、配置事務註解驅動、每個數據源對應的事務管理器,並定義“限定符”

Xml代碼 複製代碼 收藏代碼
  1. <tx:annotation-driven/>  
  2.   
  3. <bean id="transactionManager1" class="org.springframework.jdbc.DataSourceTransactionManager">  
  4. ...   
  5. <qualifier value="order"/>  
  6. </bean>  
  7. <bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">  
  8. ...   
  9. <qualifier value="account"/>  
  10. </bean>   
 

2、在需要事務的地方,指定“限定符”

 

 

Java代碼 複製代碼 收藏代碼
  1. public class TransactionalService {   
  2.   
  3. @Transactional("order")   
  4. public void setSomething(String name) { ... }   
  5.   
  6. @Transactional("account")   
  7. public void doSomething() { ... }   
  8. }  
public class TransactionalService {

@Transactional("order")
public void setSomething(String name) { ... }

@Transactional("account")
public void doSomething() { ... }
}
 


3、如果不指定“限定符”,將默認使用“transationManager”命名對應的事務管理器

Java代碼 複製代碼 收藏代碼
  1. The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found  
The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found
 

 

呼呼,小改進,大作用啊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章