1. 程式人生 > >Mybatis事務管理-jdbc事務

Mybatis事務管理-jdbc事務

一、mybatis.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"
	default-lazy-init="true">

	<!-- 配置資料來源 -->
	<bean id="dataSourceMybatisMysql" class="org.logicalcobwebs.proxool.ProxoolDataSource">
		<property name="driver">
			<value>${driver.mysql}</value>
		</property>
		<property name="driverUrl">
			<value>${url.mysql}</value>
		</property>
		<property name="user" value="${user.mysql}" />
		<property name="password" value="${pwd.mysql}" />
		<property name="alias" value="dataSourceMybatisMysqlAlis" />
		<property name="prototypeCount" value="0" />
		<property name="maximumConnectionCount" value="1000" />
		<property name="minimumConnectionCount" value="10" />
		<property name="simultaneousBuildThrottle" value="1000" />
		<property name="houseKeepingTestSql" value="select CURRENT_DATE" />
	</bean>

	<!-- 配置會話工廠 -->
	<bean id="sessionFactoryMybatis" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSourceMybatisMysql" />
		<property name="typeAliasesPackage" value="cn.*.mybatis.domain" />
		<!-- 分頁 -->
		<!-- 自定義分頁處理 -->
		<property name="plugins">
			<list>
				<bean class="cn.hard.common.mybatis.plugin.OffsetLimitInterceptor">
					<property name="dialectClass" value="cn.hard.common.jdbc.dialect.MysqlDialect" />
				</bean>
			</list>
		</property>
	</bean>
	
	<!-- 掃描DAO/Mapper -->
	<bean id="mapperScan" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="cn..*.mybatis.mypersist" />
	</bean>
	
	<!-- 事務管理 -->
	<bean id="transactionManagerJdbc" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSourceMybatisMysql" />
	</bean>
	<tx:annotation-driven transaction-manager="transactionManagerJdbc" />
</beans>

注:如果有其他資料連線池使用DataSourceTrasactionManager來處理事務,則事務處理不會成功(如下圖)。因此,這種方式只能一個數據連線池使用。(不知道怎麼回事,如果有知道的請給我留個言,不勝感激。)

jdbc.xml:同一個專案同時存在兩個事務管理,且都是引用DataSourceTransactionManager,則事務管理不會成功。可註釋其中一個事務管理。

....

<bean id="jdbcTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource">
		<ref local="dataSourceJdbcMysql" />
	</property>
</bean>
<tx:annotation-driven transaction-manager="jdbcTxManager" />

....

<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的引用,通知會使用該引用。

二、DAO/Mapper:略。(我們的事務管理放在service介面處)

三、事務管理的介面類及方法:

介面類:

public interface IQuestionService {
	
	@Transactional(rollbackFor = Exception.class,isolation=Isolation.SERIALIZABLE)
	public abstract void saveOrUpdate() throws Exception;
	
}

說明:1、rollbackFor:回滾條件;2、isolation:事務隔離級別;3、SERIALIZABLE:禁止髒讀、不可重複讀和幻讀。

實現類:

@Service("questionService")
public class QuestionServiceImpl implements IQuestionService {
	
	@Override
	public void saveOrUpdate() throws Exception{
		
		//執行第一個sql,程式碼略
		boolean result1=true;
		if(!result1){
			//丟擲異常,則將不再執行第二個sql
			throw new Exception("操作失敗!");
		}
		
		//執行第二個sql,程式碼略
		boolean result2=true;
		if(!result2){
			//丟擲異常,則第一個sql將回滾
			throw new Exception("操作失敗!");
		}
	}
}

四、@Transactional的屬性

屬性名

型別

說明

isolation

列舉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標註的位置:

1、@Transactional註解可以標註在類和方法上,也可以標註在定義的介面和介面方法上。

2、如果我們在介面上標註@Transactional註解,會留下這樣的隱患:因為註解不能被繼承,所以業務介面中標註的@Transactional註解不會被業務實現類繼承。所以可能會出現不啟動事務的情況。所以,Spring建議我們將@Transaction註解在實現類上。

3、在方法上的@Transactional註解會覆蓋掉類上的@Transactional。