被忽略的Spring3小改进—支持多数据源的@Transactional事务注解

问题描述

有个项目在配置Spring事务时,使用了@Transactional注解,但这个项目使用了多个数据源,而事务注解只对第一个起作用,咋办?

探幽

先回顾一下之前个人习惯使用的 + 配置方式,大致步骤如下:

1)定义与事务管理器对应的事务通知
2)配置需要拦截的方法调用切面
3)将切入点连接到相应的事务通知

整个系统的事务,三下配置,一处搞定,相比注解方式,个人觉得更简单、省力、统一。

但是在spring2.5以前,对分布式多数据源不支持,但是在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、配置事务注解驱动、每个数据源对应的事务管理器,并定义“限定符”

<!-- 开启注解式事务扫描 -->
<tx:annotation-driven/>

  <bean id="transactionManager1" class="org.springframework.jdbc.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource1">
    <qualifier value="order"/>
  </bean>

  <bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource2">
    <qualifier value="account"/>
  </bean>

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

public class TransactionalService {

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

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

3、如果不指定“限定符”,将默认使用“transationManager”命名对应的事务管理器

The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found.

在配置文件中,默认情况下,<tx:annotation-driven>会自动使用名称为transactionManager的事务管理器。所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>

@Transactional的属性

这里写图片描述

配置优化

可以自定义一个绑定到特定事务管理器的注解,然后直接使用这个自定义的注解进行标识:

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("tran_1")
public @interface CustomerTransactional {

}

在Service代码中使用:

...
//使用名为tran_1的事务管理器
@CustomerTransactional
public void addTest(String str){

}
…
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechGenius

文章很值,请作者喝一杯咖啡吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值