spring 事務 @Transactional註解參數 tx:annotation-driven

首先修改applicationContext.xml如下:

…
<!-- 定義一個數據源 -->
<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" />
…

 實現類代碼:

@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標註的位置
@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){
	
}
…


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章