Spring3事务管理——使用@Transactional 注解

先让我们看代码吧!
以下代码为在“Spring3事务管理——基于tx/aop命名空间的配置”基础上修改。首先修改applicationContext.xml如下:

… <!-- 定义一个数据源 -->
<beanid="dataSource"class="org.apache.tomcat.jdbc.pool.DataSource"> 
	<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/> 
	<propertyname="url"value="jdbc:mysql://localhost:3306/spring_test"/> 
	<propertyname="username"value="root"/> 
	<propertyname="password"value="root"/> 
</bean> 
<!-- 定义JdbcTemplate的Bean -->
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"
	p:dataSource-ref="dataSource"> 
</bean> 

<!-- 配置事务管理器 -->
<beanid="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
	p:dataSource-ref="dataSource"> 
</bean> 

<!-- enables scanning for @Transactional annotations -->
<tx:annotation-driventransaction-manager="txManager"/> 

<!-- 在该Bean的代码中标注@Transactional可以被事务管理器注入 -->
<beanid="userScore"
	class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"
	p:userScoreRepository-ref="userScoreRepository_jdbc"/> 
	
<beanid="userScoreRepository_jdbc"
	class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"
	p:jdbcTemplate-ref="jdbcTemplate"/> 
…

 实现类代码:

@Transactional public class UserScoreRepositoryImpl implements UserScoreRepository {
      ​ private JdbcTemplate jdbcTemplate;
      ​ @Override
      ​ public UserScore getUserSocore(String userNo) {
      ​      ​ final UserScore us = new UserScore();
      ​      ​ ...
      ​      ​ return us;
      ​ }
...
}

OK了!以上就实现了简单的事务管理了。现在再稍微了解下@Transactional。
在配置文件中,默认情况下,<tx:annotation-driven>会自动使用名称为transactionManager的事务管理器。所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>。如下:

<!-- 配置事务管理器 -->
<bean id="transactionManager"
      ​ class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      ​ p:dataSource-ref="dataSource">
</bean>
<!-- enables scanning for @Transactional annotations -->
<tx:annotation-driven/>


<tx:annotation-driven>一共有四个属性如下,

  • mode:指定Spring事务管理框架创建通知bean的方式。可用的值有proxy和aspectj。前者是默认值,表示通知对象是个JDK代理;后者表示Spring AOP会使用AspectJ创建代理
  • proxy-target-class:如果为true,Spring将创建子类来代理业务类;如果为false,则使用基于接口的代理。(如果使用子类代理,需要在类路径中添加CGLib.jar类库)
  • order:如果业务类除事务切面外,还需要织入其他的切面,通过该属性可以控制事务切面在目标连接点的织入顺序。
  • transaction-manager:指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用
 

@Transactional的属性

属性名

类型

说明

isolation

枚举org.springframework.transaction.annotation.Isolation的值

事务隔离级别

noRollbackFor

Class<? extends Throwable>[]

一组异常类,遇到时不回滚。默认为{}

noRollbackForClassName

Stirng[]

一组异常类名,遇到时不回滚,默认为{}

propagation

枚举org.springframework.transaction.annotation.Propagation的值

事务传播行为

readOnly

boolean

事务读写性

rollbackFor

Class<? extends Throwable>[]

一组异常类,遇到时回滚

rollbackForClassName

Stirng[]

一组异常类名,遇到时回滚

timeout

int

超时时间,以秒为单位

value

String

可选的限定描述符,指定使用的事务管理器

@Transactional标注的位置
@Transactional注解可以标注在类和方法上,也可以标注在定义的接口和接口方法上。
如果我们在接口上标注@Transactional注解,会留下这样的隐患:因为注解不能被继承,所以业务接口中标注的@Transactional注解不会被业务实现类继承。所以可能会出现不启动事务的情况。所以,Spring建议我们将@Transaction注解在实现类上。
在方法上的@Transactional注解会覆盖掉类上的@Transactional。

使用不同的事务管理器
如果我们要程序中使用多个事务管理器(主要是针对多数据源的情况),可以通过以下的方式实现:
Service代码:

public class MultiTxService {
      ​ @Transactional("tran_1")
      ​ public void addTest(int id){
      ​ }
      ​ @Transactional("tran_2")
      ​ public void deleteTest(int id){
      ​ }
}

applicationContext.xml配置如下: 

<bean id="tran_1"
      ​ class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      ​ p:dataSource-ref="dataSource">
      ​ <qualifier value="tran_1"/>
</bean>
<bean id="tran_2"
      ​ class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      ​ p:dataSource-ref="dataSource">
      ​ <qualifier value="tran_2"/>
</bean>

经过以上的代码,每个事务都会绑定各自的独立的数据源,进行各自的事务管理。我们可以优化下以上代码,可以自定义一个绑定到特定事务管理器的注解,然后直接使用这个自定义的注解进行标识:

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

在Service代码中使用:

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

 

来源:http://my.oschina.net/guanzhenxing/blog/214228

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值