1. 程式人生 > >Java Spring-事務管理概述

Java Spring-事務管理概述

dot nat 框架 3.0 信息 commit int 效率 cti

2017-11-11 23:05:39

事務(Transaction):是邏輯上一組操作,要麽全都成功,要麽全都失敗。

一、事務的特性

  • 原子性:事務不可分割
  • 一致性:事務執行的前後,數據完整性保持一致
  • 隔離性:一個事務執行的時候,不應該受到其他事務的打擾
  • 持久性:一旦結束,數據就永久的保存到數據庫

如果不考慮隔離性:
臟讀 :一個事務讀到另一個事務未提交數據

  當一個事務正在多次修改某個數據,而在這個事務中這多次的修改都還未提交,這時一個並發的事務來訪問該數據,就會造成兩個事務得到的數據不一致。例如:用戶A向用戶B  轉賬100元,對應SQL命令如下:

update account set money=money+100 where name=’B’;  (此時A通知B)
update account set money=money - 100 where name=’A’;

  當只執行第一條SQL時,A通知B查看賬戶,B發現確實錢已到賬(此時即發生了臟讀),而之後無論第二條SQL是否執行,只要該事務不提交,則所有操作都將回   滾,那  麽當B以後再次查看賬戶時就會發現錢其實並沒有轉。
不可重復讀 :一個事務讀到另一個事務已經提交數據(update)導致一個事務多次查詢結果不一致

  例如事務T1在讀取某一數據,而事務T2立馬修改了這個數據並且提交事務給數據庫,事務T1再次讀取該數據就得到了不同的結果,發送了不可重復讀。

  不可重復讀和臟讀的區別是,臟讀是某一事務讀取了另一個事務未提交的臟數據,而不可重復讀則是讀取了前一事務提交的數據。

  在某些情況下,不可重復讀並不是問題,比如我們多次查詢某個數據當然以最後查詢得到的結果為主。但在另一些情況下就有可能發生問題,例如對於同一個數據A  和B依次查詢就可能不同,A和B就可能打起來了
虛讀

:一個事務讀到另一個事務已經提交數據(insert)導致一個事務多次查詢結果不一致

  幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行數據項,而這個數據  項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這  就是發生了幻讀。

二、MySQL數據庫提供的四種隔離級別

  ① Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生。

  ② Repeatable read (可重復讀)

:可避免臟讀、不可重復讀的發生。

  ③ Read committed (讀已提交):可避免臟讀的發生。

  ④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。

以上四種隔離級別最高的是Serializable級別,最低的是Read uncommitted級別,當然級別越高,執行效率就越低。像Serializable這樣的級別,就是以鎖表的方式(類似於Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時選用何種隔離級別應該根據實際情況。在MySQL數據庫中默認的隔離級別為Repeatable read (可重復讀)

三、Spring提供事務管理API

  • PlatformTransactionManager:平臺事務管理器.
commit(TransactionStatus status)
getTransaction(TransactionDefinition definition)
rollback(TransactionStatus status)
  • TransactionDefinition:事務定義
ISOLation_XXX:事務隔離級別.
PROPAGATION_XXX:事務的傳播行為.(不是JDBC中有的,為了解決實際開發問題.)
TIMEOUT_DEFAULT:過期時間
  • TransactionStatus:事務狀態
是否有保存點
是否一個新的事務
事務是否已經提交

關系:PlatformTransactionManager通過TransactionDefinition設置事務相關信息管理事務,管理事務過程中,產生一些事務狀態:狀態由TransactionStatus記錄。

四、事務管理三個API詳解

  • PlatformTransactionManager:平臺事務管理器接口

Spring為不同的持久化框架提供了不同PlatformTransactionManager接口實現,前兩種最常用:

  1. org.springframework.jdbc.datasource.DataSourceTransactionManager : 使用Spring JDBC或iBatis 進行持久化數據時使用
  2. org.springframework.orm.hibernate3.HibernateTransactionManager : 使用Hibernate3.0版本進行持久化數據時使用
  3. org.springframework.orm.jpa.JpaTransactionManager : 使用JPA進行持久化時使用
  4. org.springframework.jdo.JdoTransactionManager : 當持久化機制是Jdo時使用
  5. org.springframework.transaction.jta.JtaTransactionManager : 使用一個JTA實現來管理事務,在一個事務跨越多個資源時必須使用
  • TransactionDefinition:事務定義

* 隔離級別

  1. ISOLATION_DEFAULT:默認級別. Mysql repeatable_read,oracle read_commited
  2. ISOLATION_READ_UNCOMMITTED
  3. ISOLATION_READ_COMMITTED
  4. ISOLATION_REPEATABLE_READ
  5. ISOLATION_SERIALIZABLE

* 事務的傳播行為

不是JDBC事務管理,用來解決實際開發的問題。

傳播行為:解決業務層之間的調用的事務的關系,有七種傳播行為:

  • PROPAGATION_REQUIRED :支持當前事務,如果不存在 就新建一個

    * A,B 如果A有事務,B使用A的事務,如果A沒有事務,B就開啟一個新的事務.(A,B是在一個事務中。)

  • PROPAGATION_SUPPORTS :支持當前事務,如果不存在,就不使用事務

    * A,B 如果A有事務,B使用A的事務,如果A沒有事務,B就不使用事務.

  • PROPAGATION_MANDATORY :支持當前事務,如果不存在,拋出異常

    * A,B 如果A有事務,B使用A的事務,如果A沒有事務,拋出異常.

  • PROPAGATION_REQUIRES_NEW :如果有事務存在,掛起當前事務,創建一個新的事務

    * A,B 如果A有事務,B將A的事務掛起,重新創建一個新的事務.(A,B不在一個事務中.事務互不影響.)

  • PROPAGATION_NOT_SUPPORTED :以非事務方式運行,如果有事務存在,掛起當前事務

    * A,B 非事務的方式運行,A有事務,就會掛起當前的事務.

  • PROPAGATION_NEVER :以非事務方式運行,如果有事務存在,拋出異常
  • PROPAGATION_NESTED :如果當前事務存在,則嵌套事務執行

    * 基於 SavePoint 技術.
    * A,B A有事務,A執行之後,將A事務執行之後的內容保存到SavePoint.B事務有異常的話,用戶需要自己
    設置事務提交還是回滾.

常用:
PROPAGATION_REQUIRED
PROPAGATION_REQUIRES_NEW
PROPAGATION_NESTED

Java Spring-事務管理概述