1 Spring事務管理機制
1.1 Spring框架的介紹
Spring框架是開發(fā)人員使用的最流行的一個框架.
1.2 Spring事務管理的優(yōu)點
- 提供統(tǒng)一的API接口支持不同的數(shù)據(jù)源
Sring本身沒有提供任何事務支持,只是對外提供統(tǒng)一的編程API接口,讓數(shù)據(jù)源驅(qū)動方來對Spring事務進行實現(xiàn),Spring事務的核心是PlatformTransactionManager接口.
- 提供了聲明式的事務管理
Spring的事務實現(xiàn)可以是編程式和聲明式,聲明式的事務管理運用的是SpringAOP的思想大量減少事務代碼,讓開發(fā)人員把注意力集中到具體的業(yè)務實現(xiàn)上.
- 方便和和Spring的框架進行好的集成
Spring事務管理自然可以很好的和Spring的其他框架相互兼容.
- 多個數(shù)據(jù)源的事務管理,同步
Spring支持多個數(shù)據(jù)源和多個事務管理同步進行.
1.3 Spring事務管理接口

Spring對外提供三個比較重要的接口,分別是PlatformTransactionManager,TransactionDefinition,TransactionStatus
PlatformTransactionManager是一個接口,具體由數(shù)據(jù)源廠家實現(xiàn),里面定義了獲取事務,提交和事務回滾的方法.常用的實現(xiàn)類有:
- DataSourceTransactionManager : JDBC的事務實現(xiàn)
- JpaTransactionManager : Jpa事務實現(xiàn)
- JMSTransactionManager : Jms事務實現(xiàn)
- JtaTransactionManager : Jta事務實現(xiàn)
TransactionDefinition是一個事務定義的接口,這個接口中定義了事務的隔離等級和傳播等級的常量,常用的方法是獲取到該事務的傳播機制,隔離等級,超時時間,是否是只讀事務.

TransactionStatus是一個事務狀態(tài)的接口,這個接口描述了事務運行過程中有哪些狀態(tài),比如是否是一個新的事務,存盤點,是否已經(jīng)回滾,事務是否已經(jīng)完成等.
具體使用方法是我們可以通過創(chuàng)建一個TransactionDefinition傳參給PlatformTransactionManager從而得到一個事務,返回TransactionStatus.
1.4 Spring事務定義
在TransactionDefinition中,我們可以定義事務的一系列參數(shù),其中比較重要的就是事務的隔離等級和事務的傳播機制.
事務的隔離等級:具體參考<事務的介紹>
// 和數(shù)據(jù)庫的隔離機制保持一致
ISOLATION_DEFAULT
// 讀未提交
ISOLATION_READ_UNCOMMITTED
// 讀提交
ISOLATION_READ_COMMITTED
// 可重復讀
ISOLATION_REPEATABLE_READ
// 可序列化:線性讀取
ISOLATION_SERIALIZABLE
事務的傳播機制:簡單的講就是我有兩個Service,其中一個Service調(diào)用了另外一個Service,兩個Service相互調(diào)用的時候,他們之間的事務是如何傳播的
// 如果當前沒有事務,就新建一個事務,如果已經(jīng)存在一個事務中,加入到這個事務中。這是最常見的選擇。
PROPAGATION_REQUIRED
// 支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行。
PROPAGATION_SUPPORTS
// 使用當前的事務,如果當前沒有事務,就拋出異常。
PROPAGATION_MANDATORY
// 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_REQUIRES_NEW
// 以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NOT_SUPPORTED
// 以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。
PROPAGATION_NEVER
// 如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行與PROPAGATION_REQUIRED類似的操作。
PROPAGATION_NESTED
通常如果我們不配置事務傳播機制,默認使用的是PROPAGATION_REQUIRED,就是默認是在事物中運行的.
Spring的事務實現(xiàn)
- 編程式事務實現(xiàn)原理
主要是將業(yè)務代碼包圍在try...catch當中,如果整個業(yè)務完成,就進行事務提交.否則出錯就進行事物回滾.

- 聲明式事務管理
聲明式事務管理有兩種方式進行配置,一種是在spring-context.xml文件中進行配置,一種是使用@Transactional的標簽進行配置.
無論哪種聲明式配置,本質(zhì)上都是使用了Spring的AOP思想,對于聲明式事務類生成一個對應的代理類,然后在具體的業(yè)務方法前后增加事務代碼.
Spring事務實例
1. Spring-data jpa事務管理
下面將分別使用Spring的聲明式事物管理是編程式事務管理來進行JPA事務管理的演示,代碼如下.

測試:將事務的傳播機制修改為PROPAGATION_SUPPORTS,并制作一個錯誤,使用無事務Controller調(diào)用,查看數(shù)據(jù)是否能入庫:


測試結(jié)果是報錯,但是數(shù)據(jù)正常入庫,因為調(diào)用者無事務,所以數(shù)據(jù)插入后報錯,沒有事務回滾,數(shù)據(jù)正常入庫.
2. Spring-jms 事務管理
2.1 Spring-JMS的原生事務
Spring在整合了JMS之后,我們通常是使用JmsTemplate來發(fā)送消息,使用JmsListener來監(jiān)聽消息.
這兩種方式的上都是使用通過ConnectionFactory的工廠類獲取到一個Session對象來操作消息隊列的.
其中Spring-jms的原生事務是通過session來操作的.Session對象中包含相應的Commit,rollback操作

2.2 JMSTransactionManager來對JMS進行事務管理

通過Spring容器中創(chuàng)建JMSTransaction來對發(fā)送消息和監(jiān)聽消息進行事務管理.本質(zhì)上對Session的事務管理進行了封裝,使用JmsTransactionManager來管理事務.
在一個方法中業(yè)務復雜則可能既涉及到消息的讀取,同時還有消息的寫入,使用TransactionManager進行事務管理,必須保證讀取消息和寫消息的是同一個Session.
JMSTransactionManager可配置如下:

服務層:

控制層:

測試結(jié)果:

總結(jié)
- Spring對外提供了統(tǒng)一的API接口來PlatformTransactionManager來進行事物管理.
- Spring事務管理包括了事務的隔離屬性,傳播機制,超時時間以及常用的提交和回滾操作.
- Spring事務包括了聲明式事物和編程式事務,其中聲明式事務是通過Spring的AOP機制來實現(xiàn)的.
- Spring事務常用實現(xiàn)有:DataSourceTransactionManager,JpaTransactionManager,JMSTransactionManager,JtaTransactionManager
- 代碼地址:https://github.com/lilike/chawuzhi.git