Spring3事務管理——使用原始的TransactionProxyFactoryBean

Spring的早期版本用戶必須經過TransactionProxyFactoryBean代理對須要事務管理的業務類進行代理,便於實施事務功能的加強。
讓咱們先看代碼吧!
業務層代碼:
java

public interface UserScoreService {
	public UserScore getUserSocore(String userNo);
	public void addUserScore(UserScore us);
	public int getUsableScore(String userNo);
}
public class UserScoreServiceImpl implements UserScoreService {
	private UserScoreRepository userScoreRepository;
	public void setUserScoreRepository(UserScoreRepository userScoreRepository) {
		this.userScoreRepository = userScoreRepository;
	}
	@Override
	public UserScore getUserSocore(String userNo) {
		return userScoreRepository.getUserSocore(userNo);
	}
	@Override
	public void addUserScore(UserScore us) {
		userScoreRepository.addUserScore(us);
	}
	@Override
	public int getUsableScore(String userNo) {
		return userScoreRepository.getUsableScore(userNo);
	}
}

持久層代碼: mysql

public interface UserScoreRepository {
	public UserScore getUserSocore(String userNo);
	public void addUserScore(UserScore us);
	public int getUsableScore(String userNo);
}
public class UserScoreRepositoryImpl implements UserScoreRepository {
	private JdbcTemplate jdbcTemplate;
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	@Override
	public UserScore getUserSocore(String userNo) {
		
		final UserScore us = new UserScore();
		
		StringBuffer sql = new StringBuffer();
		sql.append("select * from userscore where userNo = ?");
		
		jdbcTemplate.query(sql.toString(), new Object[]{userNo}, new RowCallbackHandler() {
			
			@Override
			public void processRow(ResultSet rs) throws SQLException {
				us.setId(rs.getInt("id"));
				us.setHonourScore(rs.getInt("honourScore"));
				us.setUsableScore(rs.getInt("usableScore"));
				us.setUserName(rs.getString("userName"));
				us.setUserNo(rs.getString("userNo"));
			}
		});
		return us;
	}
	@Override
	public void addUserScore(UserScore us) {
	}
	@Override
	public int getUsableScore(String userNo) {
		return 0;
	}

}

Spring配置文件: web

<!-- 定義一個數據源 -->
<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="userScoreRepository_jdbc"
	class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"
	p:jdbcTemplate-ref="jdbcTemplate" />
	

<!-- 聲明事務管理器 -->
<bean id="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 須要實施事務加強的目標業務Bean -->
<bean id="userScoreTarget"
	class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"
	p:userScoreRepository-ref="userScoreRepository_jdbc" />
	
<!-- 使用事務代理工廠類爲目標業務Bean提供事務加強 -->
<!-- p:transactionManager-ref="txManager"  指定事務管理器 -->
<!-- p:target-ref="userScoreTarget" 指定目標業務Bean -->
<bean id="userScore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
	p:transactionManager-ref="txManager" 
	p:target-ref="userScoreTarget">
	
	<property name="transactionAttributes">
		<props>
			<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>	<!-- 只讀事務 -->
			<prop key="*">PROPAGATION_REQUIRED</prop>	<!-- 可寫事務 -->
		</props>
	</property>
	
</bean>


web.xml配置
spring

<context-param>
	<param-name>log4jConfigLocation</param-name>
	<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


異常回滾/提交規則
上面spring配置中的<prop>內的值爲事務屬性信息,匹配格式爲: sql

PROPAGATION 數據庫

(傳播行爲) apache

tomcat

ISOLATION app

(隔離級別(可選)) ide

readOnly

(是否爲只讀事務(可選))

-Exceptions

(發生這些異常時回滾事務(可選))

 

+Exceptions

(發生這些異常時照樣提交事務(可選))


Spring事務的傳播類型
Spring在TransactionProxyFactory接口中規定了7種類型的事務傳播行爲,它們規定了事務方法和事務發生嵌套調用時候是怎麼傳播的。如:

事務傳播行爲類型

說明

PROPAGATION_REQUIRED

若是當前沒有事務,就新建一個事務;若是已經存在一個事務,加入到這個事務中。(這個是最多見的選擇)

PROPAGATION_SUPPORTS

支持當前事務。若是當前沒有事務,就以非事務方式執行

PROPAGATION_MANDATORY

使用當前的事務。若是當前沒有事務,就拋出異常

PROPAGATION_REQUIRES_NEW

新建事務。若是當前存在事務,就把當前事務掛起

PROPAGATION_NOT_SUPPORTED

以非事務的方式執行操做。若是當前存在事務,就把當前事務掛起

PROPAGATION_NEVER

以非事務方式執行。若是當前存在事務,則拋出異常

PROPAGATION_NESTED

若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與

PROPAGATION_REQUIRED相似的操做


隔離級別
隔離級別是可選的,默認的爲ISOLATION_DEFAULT,表示數據庫的默認隔離級別。隔離級別的值以下:

隔離級別

髒讀

不可重複讀

幻象讀

第一類丟失更新

第二類丟失更新

ISOLATION_READ_UNCOMMITED

容許

容許

容許

不容許

容許

ISOLATION_READ_COMMITED

不容許

容許

容許

不容許

容許

ISOLATION_REPEATABLE_READ

不容許

不容許

容許

不容許

不容許

ISOLATION_SERIALIZABLE

不容許

不容許

不容許

不容許

不容許

 

默認狀況下,當發生運行異常時,事務將被回滾,發生檢查型異常時,既不回滾也不提交,控制權交給外層調用。因此,帶負號的異常設置僅對檢查型異常有意義。

相關文章
相關標籤/搜索