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的引用,通知會使用該引用。
三、事務管理的介面類及方法:
介面類:
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。