事務就是一組數據庫操做,但這組操做是具備原子性的(atomic)。所謂原子操做,即這組數據庫操做要麼就都執行成功,要麼就一個也沒執行。當有一些操做成功了(「成功」指數據庫裏的數據已更新或提交),但中間出現異常,後邊的也就沒法執行時,事務要回滾,即恢復到什麼也沒執行之前的狀態。spring
舉個比較常見的例子,一位顧客要進行銀行轉賬,把100元從A賬戶轉到B賬戶,通常的過程是把A賬戶的總額減去100,B賬戶的總額加上100(只考慮最簡單狀況)。當在A賬戶總額減去100後出現異常狀況,使得沒法再對B賬戶進行操做。若是沒使用事務,那麼這位顧客就損失了100元,但若是使用了事務,那麼出現異常後,事務回滾,使得A賬戶總額恢復到減去100之前的金額。雖然使用事務並無達到顧客轉賬的目的,但避免了出現異常狀況時顧客的損失。數據庫
事務就至關於咱們作一件事情(這件事由許多小的步驟組成),要麼咱們就把這件事情完完整整地作成功,要麼咱們就一點也不要作。不能作到半截撂攤子不幹了。 |
回到Spring來,Spring的Dao框架對事務提供了強大的支持。它包括有兩種事物管理,即:編程
編程式事物管理(programmatic tansaction management)框架
聲明式事物管理(Declarative tansaction management)優化
所謂編程式事物管理,就是把事物管理以代碼的形式編寫到你的應用中要使用事物管理的地方,靈活性較強。而聲明式事物管理是以配置文件的形式在xml文件中定義,好處是不具備代碼入侵性,當不須要事物管理時,能夠直接修改配置文件,而不用修改代碼。之後會介紹這兩種事物管理。atom
在Spring中,主要涉及如下幾種事物屬性:spa
1. 傳播行爲(propagation behavior)xml
它是對事物的起始,暫停,終止時刻的定義,主要有如下幾種接口
參數 | 含義 |
PROPAGATION_REQUIRED | 若是存在事物的話,就繼續這個事物,若是不存在,新建一個事物。 |
PROPAGATION_SUPPORTS | 若是存在事物的話,就繼續這個事物,若是不存在,就以非事務的方式進行。 |
PROPAGATION_MANDATORY | 必須在現存事物中執行,不然拋出異常。 |
PROPAGATION_REQUIRES_NEW | 創建一個新事物,若是現存一個事物,則暫停它。 |
PROPAGATION_NOT_SUPPORTED | 再也不事務中執行,若是現存事物,則暫停它。 |
PROPAGATION_NEVER | 再也不事務中執行,若是現存事物,則拋出異常。 |
PROPAGATION_NESTED | 在一個嵌入的事物中執行,不然同PROPAGATION_REQUIRED |
上述參數是在org.springframework.transaction.TransactionDefinition接口中定義的(類型是public static final,值從0到6)。上述參數中最經常使用的是PROPAGATION_REQUIRED。事務
2. 隔離等級(isolation level)
在一個應用應用程序中,可能有多個事務在運行,這時就會產生一些問題。
dirty read
一個事物更新了數據庫中的某些數據,另外一個事物讀取了這些數據,這時前一個事物因爲某些緣由回滾了,那麼第二個事物讀取的數據就是「髒數據」。
non-repeatable read
一個事物須要兩次查詢同一數據,但兩次查詢中間可能有另一個事物更改了這個數據,致使前一個事物兩次讀出的數據不一致。
phantom read
一個事物兩次查詢同一個表,但兩次查詢中間可能有另一個事物又向這個表中插入了一些新數據,致使前一個事物的兩次查詢不一致。
爲了解決以上問題,Spring的事物管理定義了一些隔離級別,所謂「隔離」,即對數據的鎖定。
參數 | 含義 |
ISOLATION_DEFAULT | 使用數據庫默認的隔離級別 |
ISOLATION_READ_UNCOMMITTED | 允許事物讀取其餘並行事物還未提交的數據。這種級別會出現上面三種狀況。 |
ISOLATION_READ_COMMITTED | 允許事物讀取其餘並行事物已經提交(commit)的數據,可防止dirty read |
ISOLATION_REPEATABLE_READ | 這種級別會能夠防止上面三種狀況發生。 |
ISOLATION_SERIALIZABLE | 使用事物鎖,鎖定相應數據,能夠防止上面三種狀況發生,但效率比較低。 |
上述參數也是在org.springframework.transaction.TransactionDefinition接口中定義的(類型是public static final,值爲-1,1,2,4,8)。上述參數中最經常使用的是ISOLATION_DEFAULT。
3. read only
應用這項屬性時,底層的數據庫能夠對讀取進行最優化,但要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用,即只能在事物中使用。
4. timeout
在多事物並行狀況下,爲了保證正確性,有些事物的操做會有延遲,甚至死鎖。設置事物超時時間,能夠避免事物的長時間等待。設置事物超時時間也要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用。
以上的四種屬性及其相應方法都定義在org.springframework.transaction.TransactionDefinition接口及其實現類(如org.springframework.transaction.support.DefaultTransactionDefinition)裏。