天天看點

事務管理事務管理

事務管理

目的

  • 在出現異常的情況下,保證資料的一緻性;資料送出操作復原至異常發生前的狀态

設計

  • 項目系統設計階段需要考慮每個功能中是否需要使用到事務
    • 切忌開發過程中為了開發而開發
    • 切忌在不知道為什麼用事務的情況下,看到别人用自己就用
  • 測試用例,開發環境或測試環境觸發異常,驗證是否發生復原

方式

  • Spring(Spring Framework 提供對事務管理的抽象接口) 支援兩種事務管理方式:
    • 程式設計式事務管理:使用TransactionTemplate或PlatformTransactionManager實作
      • 優勢:可以控制事務的粒度,最細粒度到代碼塊級别;
    • 聲明式事務管理:建立在AOP之上的。其本質是對方法前後進行攔截,然後在目标方法開始之前建立或者加入一個事務(此處取決于事務的傳播行為),在執行完目标方法之後根據執行情況送出或者復原事務(執行成功則送出,失敗則進行實物的復原)
      • 優勢:在方法外進行聲明,事務控制的代碼不會與業務邏輯代碼混在一起,最細粒度到方法級别(解決方法:可以将需要進行事務管理的代碼塊獨立為方法,通過方法間調用實作);符合spring倡導的非侵入式的開發方式,即業務處理邏輯代碼與事務管理代碼不放在一起
      • 分類
        • 基于tx和aop名字空間的xml配置檔案
        • 基于注解@Transactional的聲明式事務管理

實作

  • 程式設計式事務管理
UserTransaction utx = entityManager.getTransaction();
try{
    utx.begin();
    businessLogic();
    utx.commit();
}
catch(Exception ex) {
    utx.rollback();
    throwex;
}
           
  • 聲明式事務管理
    • 基于tx和aop名字空間的xml配置檔案
<!-- 攔截器方式配置事物 -->
	<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="*" propagation="REQUIRED" />

			<tx:method name="get*" propagation="SUPPORTS" />
			<tx:method name="find*" propagation="SUPPORTS" />
			<tx:method name="load*" propagation="SUPPORTS" />
			<tx:method name="search*" propagation="SUPPORTS" />
			<tx:method name="select*" propagation="SUPPORTS" />
		</tx:attributes>
	</tx:advice>
           
  • 聲明式事務管理
    • 基于注解@Transactional的聲明式事務管理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
			http://www.springframework.org/schema/context
			http://www.springframework.org/schema/context/spring-context-4.0.xsd
			http://www.springframework.org/schema/tx
			http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 資料源tqbase-->
    <bean id="dataDataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
    </bean>

    <bean id="dataSqlSessionFactory"
          class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="tqbaseDataSource"/>
    </bean>
    <bean id="dataTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataDataSource"/>
    </bean>
</beans>
<!-- DataSourceTransactionManager 與 SqlSessionFactoryBean 指向同一個資料源 -->
           
  • 參考資料

    - Spring-tx聲明式事務、@Transaction注解事務

參考資料

  • spring的@Transactional注解詳細用法