標籤:行資料 特性 層級 int ibatis 產生 管理 ram 分割
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:到期時間
是否有儲存點是否一個新的事務事務是否已經提交
關係:PlatformTransactionManager通過TransactionDefinition設定事務相關資訊管理事務,管理事務過程中,產生一些事務狀態:狀態由TransactionStatus記錄。
四、交易管理三個API詳解
- PlatformTransactionManager:平台交易管理員介面
Spring為不同的持久化架構提供了不同PlatformTransactionManager介面實現,前兩種最常用:
- org.springframework.jdbc.datasource.DataSourceTransactionManager : 使用Spring JDBC或iBatis 進行持久化資料時使用
- org.springframework.orm.hibernate3.HibernateTransactionManager : 使用Hibernate3.0版本進行持久化資料時使用
- org.springframework.orm.jpa.JpaTransactionManager : 使用JPA進行持久化時使用
- org.springframework.jdo.JdoTransactionManager : 當持久化機制是Jdo時使用
- org.springframework.transaction.jta.JtaTransactionManager : 使用一個JTA實現來管理事務,在一個事務跨越多個資源時必須使用
- TransactionDefinition:事務定義
* 隔離等級
- ISOLATION_DEFAULT:預設層級. Mysql repeatable_read,oracle read_commited
- ISOLATION_READ_UNCOMMITTED
- ISOLATION_READ_COMMITTED
- ISOLATION_REPEATABLE_READ
- 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-交易管理概述