什麼是事務 事務是現代資料庫的核心概念之一,它表示資料庫一系列操作的集合。這些操作必須在一個事務當中,要麼全部執行成功,要麼全部不執行。 ACID原則 原子性(Atomicity) 原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失 ...
什麼是事務
事務是現代資料庫的核心概念之一,它表示資料庫一系列操作的集合。這些操作必須在一個事務當中,要麼全部執行成功,要麼全部不執行。
ACID原則
原子性(Atomicity)
原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響。
一致性(Consistency)
一個事務執行之前和執行之後都必須處於一致性狀態。例如轉賬,假設用戶A和用戶B兩者的錢加起來一共是5000,那麼不管A和B之間如何轉賬,轉幾次賬,事務結束後兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。
隔離性(Isolation)
隔離性是當多個用戶併發訪問資料庫時,比如操作同一張表時,資料庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個併發事務之間要相互隔離。
持久性(Durability)
持久性是指一個事務一旦被提交了,那麼對資料庫中的數據的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作。
Java事務類型
JDBC事務
JDBC事務也稱之為本地事務,主要是利用Connection對象控制,可以將多個SQL語句操作放在一個事務中執行。Connection介面提供了兩種事務管理的方式:自動提交和手動提交。但是JDBC事務的一個缺點就是事務範圍局限於一個資料庫連接中,並不能誇多個資料庫。
JTA事務
JTA(Java Transaction API)是Java中的事務標準PAI,它與實現和協議無關,應用程式和應用伺服器之間可以使用JTA來操作事務。JTA事務允許應用程式同時操作多個不同的資料庫,這些資料庫可以分佈在不同的網路中,這就是所謂的分散式事務處理。而大部分資料庫的JDBC驅動都會支持這種分散式事務處理(通常都會實現XADataSource與XAConnection)。
容器事務(CMT)
容器事務主要由J2EE應用伺服器提供,通常指的是EJB容器,這些容器事務大多基於JTA事務來實現。相對於編碼來實現JTA事務管理,我們可以通過容器提供的事務管理機制來完成相同的功能。這樣我們不必以硬編碼的方式來控制事務,完全由容器托管,我們只需簡單的指定哪些方法需要加入事務,一旦指定,容器將負責事務的管理。
Spring事務管理
編程式事務
所謂編程式指的是在程式中以編碼的方式使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於編程式事務管理,spring推薦使用TransactionTemplate。
聲明式事務
聲明式事務是建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前創建或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。聲明式事務最大的優點就是不需要通過編程的方式管理事務,只需要在配置文件中做相應的配置或者使用註解進行事務聲明即可。
事務傳播性
事務的傳播性一般在事務嵌套時候使用,比如在事務A裡面調用了另外一個使用事務的方法,那麼這倆個事務是各自作為獨立的事務執行提交,還是內層的事務合併到外層的事務一塊提交,這就是事務傳播性要確定的問題。
REQUIRED
業務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那麼這個時候就會加入到該事務中,如果當前沒有事務環境的話,就會為自己創建一個新的事務。
(如果存在一個事務,則支持當前事務。如果沒有事務則開啟)
SUPPORTS
如果業務方法A在某個事務範圍內被調用,則方法成為事務的一部分。如果業務方法在事務範圍外被調用,則方法在沒有事務的環境下執行。即當標註了事務傳播屬性——SUPPORTS的業務方法在另一個bean的業務方法中執行時,如果另一個bean的業務方法開啟了事務,它就會處在事務中執行,如果另一個bean的業務方法也沒開啟事務,那麼它也在沒有事務的環境中進行。
(如果存在一個事務,則支持當前事務。如果沒有事務,則非事務的執行)
MANDATORY
該屬性指定業務方法只能在一個已經存在的事務中執行,業務方法不能發起自己的事務。如果業務方法在沒有事務的環境下調用,容器就會拋出異常。一種比較強硬的方式。
(如果存在一個事務,則支持當前事務。如果沒有一個活動的事務,則拋出異常)
REQUIRES_NEW
該屬性表明不管當前是否存在事務,業務方法總會為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務會被掛起,新的事務會被創建,直到方法執行結束,新事務才算結束,原先的事務才會恢復執行。
( 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起)
NOT_SUPPORTED
聲明方法不需要事務。如果方法沒有關聯到一個事務,容器不會為它開啟事務。如果方法在一個事務中被調用(在其他業務bean的方法中被調用了,而其他業務bean的方法是開啟了事務的),該事務會被掛起,在方法調用結束後,原先的事務便會恢復執行。
(總是非事務地執行,並掛起任何存在的事務)
NEVER
指定業務方法絕對不能在事務範圍內執行。如果業務方法在某個事務中執行,容器會拋出異常,只有業務方法沒有關聯到任何事務,才能正常執行。比較強硬的方式,就是不支持事務。
(總是非事務地執行,如果存在一個活動事務,則拋出異常)
NESTED
(嵌套事務)如果一個活動的事務存在,則當前方法運行在一個嵌套的事務中。 如果沒有活動事務,就創建一個新的事務。它使用了一個單獨的事務,這個事務擁有多個可以回滾的保存點。內部事務的回滾不會對外部事務造成影響。外部事務回滾會導致內部事務的回滾。如果被調用的內部方法沒有捕獲異常,跑出異常也會導致外部事務的回滾。
(如果一個活動的事務存在,則運行在一個嵌套的事務中。 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行 Spring事務的隔離級別)