先让咱们看代码吧!
如下代码为在“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
@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){ } …