Spring Data JPA 事務

Spring Data JPA 是 Spring 基於 ORM 框架、JPA 規範的基礎上封裝的一套 JPA 應用框架,可以使開發者用極簡的代碼便可實現對數據的訪問和操做。它提供了包括增刪改查等在內的經常使用功能,且易於擴展。如下介紹JPA事務spring

1.事務基礎:

事務的基本概念:即訪問並可能更新數據庫中各類數據項的一個程序執行單元。數據庫

須要管理事務的執行,要麼成功、要麼失敗,一但失敗,全部操做將回滾到初始狀態,一但成功,則進行持久化。session

事務特性ACID:原子性、一致性、隔離性(併發執行的事務不能相互干擾)、持久性(對數據庫的改變是永久性)併發

Spring Data JPA事務分爲:JTA事務(分佈式事務,多種數據庫)、RESOURCE_LOCAL事務(本地事務,數據庫級別,僅支持一種數據庫)app

 

2.數據庫事務併發帶來的問題

髒讀:一句話表達事務讀取了其餘併發事務未提交的數據框架

事務B讀取了事務A未提交的數據,事務B按未提交的數據進行執行並提交。而事務A又對數據進行修改後再提交。這樣事務B讀取的數據與事務A提交的數據不一致。分佈式

不可重複讀:同一個事務前後兩次或兩次以上讀取同一數據,結果不同。spa

事務C讀取了數據,事務尚未提交。hibernate

事務D修改了數據,並提交事務。隨後,事務C再次讀取時,發現數據變了。3d

幻讀:跟不可重複讀相似,側重記錄的數量(行數),不可重複讀側重於數據的值。

 

3.事務的傳播特性:

 

FunctionA調用FunctionB

1. PROPAGATION_REQUIRED: 若是存在一個事務,則支持當前事務。若是沒有事務則開啓
2. PROPAGATION_SUPPORTS: 若是存在一個事務,支持當前事務。若是沒有事務,則非事務的執行
3. PROPAGATION_MANDATORY: 若是已經存在一個事務,支持當前事務。若是沒有一個活動的事務,則拋出異常。
4. PROPAGATION_REQUIRES_NEW: 老是開啓一個新的事務。若是一個事務已經存在,則將這個存在的事務掛起。
5. PROPAGATION_NOT_SUPPORTED: 老是非事務地執行,並掛起任何存在的事務。
6. PROPAGATION_NEVER: 老是非事務地執行,若是存在一個活動事務,則拋出異常
7. PROPAGATION_NESTED:若是一個活動的事務存在,則運行在一個嵌套的事務中. 若是沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行

 

4.事務的隔離級別:

1. ISOLATION_DEFAULT: 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.另外四個與JDBC的隔離級別相對應
2. ISOLATION_READ_UNCOMMITTED: 這是事務最低的隔離級別,它充許令外一個事務能夠看到這個事務未提交的數據。這種隔離級別會產生髒讀,不可重複讀和幻像讀。
3. ISOLATION_READ_COMMITTED: 保證一個事務修改的數據提交後才能被另一個事務讀取。另一個事務不能讀取該事務未提交的數據
4. ISOLATION_REPEATABLE_READ: 這種事務隔離級別能夠防止髒讀,不可重複讀。可是可能出現幻像讀。它除了保證一個事務不能讀取另外一個事務未提交的數據外,還保證了避免下面的狀況產生(不可重複讀)。
5. ISOLATION_SERIALIZABLE 這是花費最高代價可是最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀外,還避免了幻像讀。

一般使用數據庫的默認隔離級別便可,基本不須要進行設置

MYSQL: 默認爲REPEATABLE_READ級別
SQLSERVER: 默認爲READ_COMMITTED

5.配置事務 

先在spring配置文件中引入<tx:>命名空間

5.1經過註解配置事務:

<!-- 事務管理器配置, Hibernate單數據源事務 -->
    <bean id="defaultTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <!-- 使用annotation定義事務 -->
    <tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />

 

配置完以後,就可經過@Transactional 註解的bean自動配置爲聲明式事務支持 .

注意如下問題:

a.<tx:annotation-driven/>元素的出現開啓了事務行爲,@Transactional  是元數據標記,只有在前者配置後,再使用@Transactional才能開啓事務

b.@Transactional 能夠添加到Dao層或Servive層(具體的實現類)的 public 可見度的方法上,而不要使用在類所要實現的任何接口上。你固然能夠在接口上使用 @Transactional 註解,可是這將只能當你設置了基於接口的代理時它才生效。由於註解是 不能繼承 的

 

5.2經過AOP配置事務:

    <!--事務的 AOP 配置-->
    <!--advisor-->
    <tx:advice id="applicationAdvisor" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED"/>
            <tx:method name="load*" propagation="REQUIRED" read-only="false" isolation="DEFAULT" rollback-for="UserNotFoundException,UserNotFound2Exception"/>
            <tx:method name="is*" propagation="REQUIRED" read-only="false"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:advisor advice-ref="applicationAdvisor" pointcut="execution(* com.mm.*.service.impl.*.*(..))"/>
    </aop:config>
相關文章
相關標籤/搜索