1. 程式人生 > 其它 >學習筆記--Spring的事務控制

學習筆記--Spring的事務控制

1.程式設計式事務控制相關物件

1.1 PlatformTransactionManager

該介面是Spring的事務管理器,它裡面提供了我們常用的操作事務的方法。

不同的技術,使用了不同的實現類實現該介面。

1.2 TransactionDefinition

是事務的定義資訊物件。裡面包含著事務的相關資訊。裡面有如下方法

方法 說明
int getIsolationLevel() 獲得事務的隔離級別
int getPropogationBehavior() 獲得事務的傳播行為
int getTimeout() 獲得超時時間
boolean isReadOnly() 是否只讀

1.事務隔離級別:設定隔離級別,可以解決事務併發產生的問題,如髒讀、不可重複讀和虛讀。

2.事務傳播行為。

REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中,一般的選擇。

SUPPORTS:支援當前事務,如果當前沒有事務,就以非事務方式執行(沒有事務)。

1.3 TransactionStatus

該介面的是事務具體的執行狀態。

方法 說明
boolean hasSavePoint() 是否儲存回滾點

boolean isCompleted()

事務是否完成

boolean isNewTransaction()

是否是新事務
boolean isRollbackOnly() 事務是否滾回

被動封裝事務狀態資訊。

2.基於XML的宣告式事務控制

2.1 什麼是宣告式事務控制

採用宣告的方式處理事務,這裡說的宣告,就是在配置檔案中宣告,在Spring配置檔案中宣告式的處理事務來代替程式碼式的處理事務。

作用:

事務管理不侵入開發的元件,因為事務管理是屬於系統層面的服務,不是業務邏輯的一部分。

業務邏輯物件不會意識到正在事務管理之中。

(AOP的思想)

在不需要事務管理的時候,只需要在設定檔案上修改一下,即可移除事務管理服務,無需改變程式碼。

注意:Srping宣告式事務控制底層就是AOP

AOP的延展

2.2 宣告式事務控制的實現

我們想對Service層下的transfer方法進行事務控制,目的是為了將轉出和轉入的操作作為一個事務整體,同成功同失敗。

避免出現一方轉出成功,一方轉入失敗仍然進行的問題。

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void transfer(String outMan, String inMan, double money) {
        //開啟事務
        accountDao.out(outMan,money);
        int i = 1/0;
        accountDao.in(inMan,money);
        //提交事務
    }
}

  

我們對transfer中間進行自發的一個異常錯誤,我們需要做的是在執行轉出方法前開啟事務,在轉入方法執行結束後結束事務,以達到統一的一個目的。

要達到Spring的事務控制,我們需要對xml進行控制。

    <!-- 配置一個平臺事務管理器 不同的技術實現用不同的事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 通知:事務的增強-->
    <tx:advice id="txAdive" transaction-manager="transactionManager">
        <!-- 設定事務的屬性資訊 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事務AOP的織入 -->
    <aop:config>
        <aop:advisor advice-ref="txAdive" pointcut="execution(* com.itheima.service.impl.*.*(..))"/>
    </aop:config>

  

第一個要配置的是平臺事務管理器,不同的計算對應著不同的事務管理器類,所以要注意區分,裡面需要注入DataSource屬性,因為Spring通過資料庫連線來控制事務。

第二個要配置的是事務的增強方法(與AOP不同的是不用自己定義增強類),由於用到了tx名稱空間,所以使用前要引入tx的名稱空間。這裡配置了用的平臺事務管理器,還有對不同方法的不同事務引數配置。

第三個要配置的是事務AOP的織入,與AOP一樣,pointcut裡面寫的是對什麼範圍的業務方法使用業務增強。

2.3 切點方法的事務引數配置

<!-- 通知:事務的增強-->
    <tx:advice id="txAdive" transaction-manager="transactionManager">
        <!-- 設定事務的屬性資訊 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

  

name:切點方法名稱

isolation:事務的隔離級別

propagation:事務的傳播行為

timeout:超時時間

read-only:是否只讀

3.基於註解的宣告式事務控制

3.1 快速實現

主要是將以下配置改成註解方式。

    <!-- 通知:事務的增強-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 設定事務的屬性資訊 -->
        <tx:attributes>
            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事務AOP的織入 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"/>
    </aop:config>

  

這些全部在業務方法類上進行,也就是Service層。

@Service("accountService")
@Transactional(isolation = Isolation.READ_COMMITTED)
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public void transfer(String outMan, String inMan, double money) {
        //開啟事務
        accountDao.out(outMan,money);
        int i = 1/0;
        accountDao.in(inMan,money);
        //提交事務
    }

//    @Transactional()
    public void xxx(){}
}

  

使用@Transactional註解來完成,註解可用的屬性同xml配置方式。

如果該註解出現在整個Service類上,表明該類的所有業務方法都採用該註解所對應的值來配置。

如果該註解出現在某個業務方法上,表明該業務方法的某個配置。

如果都有,服從就近原則。

xml配置檔案要開啟事件的註解驅動

<tx:annotation-driven transaction-manager="transactionManager"/>