事務(Transaction)基本概念
一.什麼是事務 事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。 事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中一個步驟失敗,將發生復原操作,撤消撤消之前到事務開始時的所以操作。
二.事務的 ACID 事務具有四個特徵:原子性( Atomicity )、一致性( Consistency )、隔離性( Isolation )和持久性( Durability )。這四個特性簡稱為 ACID 特性。 1 、原子性 事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做 2 、一致性 事務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。因此當資料庫只包含成功事務提交的結果時,就說資料庫處於一致性狀態。如果資料庫系統運行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這時資料庫就處於一種不正確的狀態,或者說是不一致的狀態。 3 、隔離性 一個事務的執行不能其它事務幹擾。即一個事務內部的操作及使用的資料對其它並發事務是隔離的,並發執行的各個事務之間不能互相干擾。 4 、持久性 也稱永久性,指一個事務一旦提交,它對資料庫中的資料的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。
二.事務的屬性 一個事務的屬性控制了事務的使用範圍。 EJB 、 Spring 以及.net下的事務屬性都很類似的, 事務屬性有如下幾種: Required:
如果在一個事務中調用,就把該方法加到此事務中來
如果還沒有啟動事務,就啟動一個新事務
RequiredNew:
不管當前有沒有事務,都會啟動一個新事務,如果當前有事務,會被掛起直到方法結束。
NotSupported:
不能在事務中執行此方法。如果有事務,將會被掛起直到方法結束。
Supports:
如果當前有事務,此方法會加到當前事務,如果沒有,容器也不會啟動新事務。
Mandatory:
必須在事務中調用此方法,否則拋出異常。
Never:
必須不在事務中調用此方法,否則拋出異常。 三.事務的復原 CMT 在以下兩中情況下,事務將復原。第一,如果產生一個系統異常,容器將自動復原該事務。第二,通過調用 EJBContext 介面 SetRollbackOnly 方法, Bean 方法通知容器復原該事務。如果 Bean 拋出一個應用異常,事務將不會自動復原,但可以調用 SetRollbackOnly 復原。 四.事務逾時 對於 EJB 中的容器管理事務,事務逾時間隔是通過設定 default.properties 檔案中 ransaction.timeout 屬性的值來確定的,該檔案在 J2EE SDK 安裝目錄的 config 子目錄下。如下例將事務逾時間隔設定為 5 秒鐘: transaction.timeout=5 ,這樣,當事務在 5 秒鐘內還沒有完成,容器將復原該事務。 J2EE SDK 安裝後,逾時間隔的預設值為 0 ,表示不計算逾時,無論事務執行多長時間,除非異常出錯復原,一直等待事務完成。 只有使用容器管理事務的企業 Bean 才會受到 transaction.timeout 屬性值的影響。 Bean 管理的 JTA 事務使用 UserTransaction 介面的 setTransactionTimeout 方法來設定事務逾時間隔。 五.隔離等級 事務不僅保證事務界限內的資料庫操作全部完成(或復原)同時還隔離資料庫更新語句。隔離等級描述被修改的資料對其他事物的可見度。隔離等級的控制會跟具體的 DBMS 廠商不同而不同。 隔離等級與並發性是互為矛盾的:隔離程度越高,資料庫的並發性越差;隔離程度越低,資料庫的並發性越好。 通過一些現象,可以反映出隔離等級的效果。這些現象有: l 更新丟失( lost update ):當系統允許兩個事務同時更新同一資料是,發生更新丟失。 l 髒讀( dirty read ):當一個事務讀取另一個事務尚未提交的修改時,產生髒讀。 l 非重複讀( nonrepeatable read ):事務多次讀取同一行中的資料卻得到不同數值時。例如:事務1讀取了一行資料,而事務2改變或刪除了那些行並提交了修改。如果事務1再次讀取了那一行,那麼,事務1就得到了不同的數值(被更新或刪除)。l 幻像讀( phantom read ):一行資料滿足搜尋規則,卻在開始沒有被看到。例如:事務1讀取了一系列滿足搜尋規則的行,而事務2插入或刪除了一個滿足事務1搜尋規則的行。如果事務1再次執行查詢語句,就會得到不同的一系列行。 SQL-99 標準定義了下列隔離等級: l 未提交讀( read uncommitted )(隔離事務的最低層級,只能保證不讀取物理上損壞的資料) l 已提交讀( read committed )(資料庫引擎 的預設層級)當一個事務運行在這個隔離等級時, 一個 SELECT 查詢只能看到查詢開始之前提交的資料,而永遠 無法看到未提交的資料,或者是在查詢執行時其他並行的事務提交做的改變。 l 可重複讀( repeatable read ),不會髒讀和非重複讀,可能發生幻像讀 l 可序列化( serializable )(隔離事務的最進階別,事務之間完全隔離)
ANSI/ISO SQL
隔離等級
| 隔離等級 |
髒讀(DirtyRead) |
不可重複的讀(Non-Repeatable Read) |
幻像 讀取(Phantom Read) |
| 未提交讀 (Read uncommitted) |
可能 |
可能 |
可能 |
| 已提交讀 (Read committed) |
不可能 |
可能 |
可能 |
| 可重複讀(Repeatable read) |
不可能 |
不可能 |
可能 |
| 可序列化(Serializable ) |
不可能 |
不可能 |
不可能 |