1. 程式人生 > >專案搭建POC之基礎spring事務

專案搭建POC之基礎spring事務

重新搭建專案POC測試用,時間有餘,將一些基本知識記錄之。

spring中配置事務:

事務是什麼:事務是由一組sql語句組成的邏輯處理單元

ACID:原子性(Atomicity)、一致性(Consistent):、隔離性(Isolation)、永續性(Durable)

1、原子性(Atomicity):事務是一個原子操作單元,其對資料的修改,要麼全都執行,要麼全都不執行

2、一致性(Consistent):在事務開始和完成時,資料都必須保持一致狀態。這意味著所有相關的資料規則都必須應用於事務的修改,以保持資料的完整性,事務結束時,所有的內部資料結構(如B樹索引或雙向連結串列)也都必須是正確的。

3、隔離性(Isolation):資料庫系統提供一定的隔離機制,保證事務在不受外部併發造作影響的獨立環境執行,這意味著事務處理過程中的中間狀態對外部是不可見的。

4、永續性(Durable):事務完成之後,它對資料的修改是永久性的,即使系統出現故障也能保持

併發事務處理帶來的問題:有問題就有隔離級別

髒讀(Dirty Reads):事務A讀取到事務B已修改但尚未提交的資料,還在這個資料基礎上做了操作,此時如果B事務回滾,A讀取的資料無效,不符合一致性要求。

不可重複讀:在同一個事務內,可能多次讀取同一個資料,如果這個事務還沒有結束,另一個事務也訪問同一條資料,並且可能修改了,那麼第一個事務中多次讀取的資料就可能不一樣,這就是不可重複讀,即原始讀取不可重複。一句話:一個事務範圍內兩個相同的查詢卻返回了不同的資料。

幻讀:一個事務按相同條件重新讀取之前檢索過的資料,卻發現其他事務插入了滿足其條件的新資料,就是幻讀。一句話:事務A讀取到了事務B提交的新增資料,不符合隔離性。InnoDB用多版本併發控制機制解決該問題

事務隔離級別:

未提交讀(Read uncommitted):最低級別,只保證不讀取物理上損壞的資料

已提交讀(Read committed):語句級

可重複讀(Repeatable read):事務級,mysql預設的

可序列化(Serializable):最高級別,事務級,也叫可序列化

專案中使用:

spring.xml:
 
<!--配置事務-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>

    <!--攔截器的方式配置事務-->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--給不同的方法設定事務傳播特性,傳播特性一共有七種 REQUIRED:如果存在一個事務,則支援當前事務。如果沒有事務則開啟
            SUPPORTS:如果存在一個事務,支援當前事務。如果沒有事務,則非事務的執行。-->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="append*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="edit*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="remove*" propagation="REQUIRED"/>
            <tx:method name="repair*" propagation="REQUIRED"/>
            <tx:method name="delAndRepair" 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="datagrid*" propagation="SUPPORTS"/>

            <tx:method name="*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

    <!--配置在哪些類中的那些方法上使用事務-->
    <aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.service.ms..*.*(..))"/>
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice"/>
    </aop:config>

還在springmvc.xml中配置:

<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

這裡不是很理解,查資料解釋為:暫時還不理解

通過aop名稱空間的<aop:aspectj-autoproxy />宣告自動為spring容器中那些配置@aspectJ切面的bean建立代理,織入切面。當然,spring在內部依舊採用AnnotationAwareAspectJAutoProxyCreator進行自動代理的建立工作,但具體實現的細節已經被<aop:aspectj-autoproxy />隱藏起來了

<aop:aspectj-autoproxy/>有一個proxy-target-class屬性,預設為false,表示使用jdk動態代理織入增強,當配為<aop:aspectj-autoproxy poxy-target-class="true"/>時,表示使用CGLib動態代理技術織入增強。不過即使proxy-target-class設定為false,如果目標類沒有宣告介面,則spring將自動使用CGLib動態代理。