先讓咱們看代碼吧!
如下代碼爲在「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){ } …