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

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

…
<!-- 定义一个数据源 -->
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/spring_test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
</bean>

<!-- 定义JdbcTemplate的Bean -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
        p:dataSource-ref="dataSource">
</bean>

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

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

<!-- 在该Bean的代码中标注@Transactional能够被事务管理器注入 -->
<bean id="userScore"
        class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"
        p:userScoreRepository-ref="userScoreRepository_jdbc" />

<bean id="userScoreRepository_jdbc"
        class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"
        p:jdbcTemplate-ref="jdbcTemplate" />
…

 实现类代码: mysql

@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/>。以下: spring

<!-- 配置事务管理器 -->
	<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>一共有四个属性以下, sql

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

 @Transactional的属性
apache

属性名 tomcat

类型 app

说明 框架

isolation ide

枚举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){
	
}
…
相关文章
相关标签/搜索