Spring Data JPA 事務


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

1.事務基礎:

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

需要管理事務的執行,要么成功、要么失敗,一但失敗,所有操作將回滾到初始狀態,一但成功,則進行持久化。

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

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

 

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

臟讀:一句話表達事務讀取了其他並發事務未提交的數據

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

不可重復讀:同一個事務先后兩次或兩次以上讀取同一數據,結果不一樣。

事務C讀取了數據,事務還沒有提交。

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

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

 

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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM