Spring框架入門(mén)必備教程-Spring事務(wù)(上篇)

Spring?的事務(wù)管理
事務(wù)原本是數(shù)據(jù)庫(kù)中的概念,在Dao 層。但一般情況下,需要將事務(wù)提升到業(yè)務(wù)層,即 Service 層。這樣做是為了能夠使用事務(wù)的特性來(lái)管理具體的業(yè)務(wù)。
在 Spring 中通常可以通過(guò)以下兩種方式來(lái)實(shí)現(xiàn)對(duì)事務(wù)的管理:
(1)?使用 Spring?的事務(wù)注解管理事務(wù)
(2)?使用AspectJ?的AOP?配置管理事務(wù)
Spring?事務(wù)管理 API
Spring 的事務(wù)管理,主要用到兩個(gè)事務(wù)相關(guān)的接口。
(1)?事務(wù)管理器接口(重點(diǎn))
事務(wù)管理器是PlatformTransactionManager 接口對(duì)象。其主要用于完成事務(wù)的提交、回滾,及獲取事務(wù)的狀態(tài)信息。

A、 常用的兩個(gè)實(shí)現(xiàn)類(lèi)
PlatformTransactionManager 接口有兩個(gè)常用的實(shí)現(xiàn)類(lèi):
DataSourceTransactionManager:使用 JDBC?或 MyBatis?進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)使用。
HibernateTransactionManager:使用 Hibernate?進(jìn)行持久化數(shù)據(jù)時(shí)使用。
B、Spring 的回滾方式(理解)
Spring 事務(wù)的默認(rèn)回滾方式是:發(fā)生運(yùn)行時(shí)異常和error 時(shí)回滾,發(fā)生受查(編譯)異常時(shí)提交。不過(guò),對(duì)于受查異常,程序員也可以手工設(shè)置其回滾方式。
C、回顧錯(cuò)誤與異常(理解)

Throwable 類(lèi)是Java 語(yǔ)言中所有錯(cuò)誤或異常的超類(lèi)。只有當(dāng)對(duì)象是此類(lèi)(或其子類(lèi)之一)的實(shí)例時(shí),才能通過(guò)Java 虛擬機(jī)或者Java 的throw 語(yǔ)句拋出。
Error 是程序在運(yùn)行過(guò)程中出現(xiàn)的無(wú)法處理的錯(cuò)誤,比如OutOfMemoryError、ThreadDeath、NoSuchMethodError 等。當(dāng)這些錯(cuò)誤發(fā)生時(shí),程序是無(wú)法處理(捕獲或拋出)的,JVM 一般會(huì)終止線程。
程序在編譯和運(yùn)行時(shí)出現(xiàn)的另一類(lèi)錯(cuò)誤稱(chēng)之為異常,它是 JVM?通知程序員的一種方式。通過(guò)這種方式,讓程序員知道已經(jīng)或可能出現(xiàn)錯(cuò)誤,要求程序員對(duì)其進(jìn)行處理。
異常分為運(yùn)行時(shí)異常與受查異常。
運(yùn)行時(shí)異常,是RuntimeException?類(lèi)或其子類(lèi),即只有在運(yùn)行時(shí)才出現(xiàn)的異常。如,NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException?等均屬于運(yùn)行時(shí)異常。這些異常由JVM?拋出,在編譯時(shí)不要求必須處理(捕獲或拋出)。但,只要代碼編寫(xiě)足夠仔細(xì),程序足夠健壯,運(yùn)行時(shí)異常是可以避免的。
受查異常,也叫編譯時(shí)異常,即在代碼編寫(xiě)時(shí)要求必須捕獲或拋出的異常 , 若 不 處 理 , 則 無(wú) 法 通 過(guò) 編 譯 。 如 SQLException, ClassNotFoundException,IOException 等都屬于受查異常。
RuntimeException 及其子類(lèi)以外的異常,均屬于受查異常。當(dāng)然,用戶自定義的Exception 的子類(lèi),即用戶自定義的異常也屬受查異常。程序員在定義異常時(shí),只要未明確聲明定義的為RuntimeException 的子類(lèi),那么定義的就是受查異常。
(2)?事務(wù)定義接口
事務(wù)定義接口 TransactionDefinition 中定義了事務(wù)描述相關(guān)的三類(lèi)常量: 事務(wù)隔離級(jí)別、事務(wù)傳播行為、事務(wù)默認(rèn)超時(shí)時(shí)限,及對(duì)它們的操作。

A、 定義了五個(gè)事務(wù)隔離級(jí)別常量(掌握)
這些常量均是以ISOLATION_開(kāi)頭。即形如 ISOLATION_XXX。
DEFAULT?: 采 用 DB 默 認(rèn) 的 事 務(wù) 隔 離 級(jí) 別 。 MySql 的 默 認(rèn) 為REPEATABLE_READ;?Oracle?默認(rèn)為READ_COMMITTED。
READ_UNCOMMITTED:讀未提交。未解決任何并發(fā)問(wèn)題。
READ_COMMITTED:讀已提交。解決臟讀,存在不可重復(fù)讀與幻讀。
REPEATABLE_READ:可重復(fù)讀。解決臟讀、不可重復(fù)讀,存在幻讀
SERIALIZABLE:串行化。不存在并發(fā)問(wèn)題。
B、定義了七個(gè)事務(wù)傳播行為常量(掌握)
所謂事務(wù)傳播行為是指,處于不同事務(wù)中的方法在相互調(diào)用時(shí),執(zhí)行期間事務(wù)的維護(hù)情況。如,A 事務(wù)中的方法doSome()調(diào)用 B 事務(wù)中的方法doOther(),在調(diào)用執(zhí)行期間事務(wù)的維護(hù)情況,就稱(chēng)為事務(wù)傳播行為。事務(wù)傳播行為是加在方法上的。
事務(wù)傳播行為常量都是以PROPAGATION_ 開(kāi)頭,形如PROPAGATION_XXX。
PROPAGATION_REQUIRED?
PROPAGATION_REQUIRES_NEW?
PROPAGATION_SUPPORTS
PROPAGATION_MANDATORY?
PROPAGATION_NESTED?
PROPAGATION_NEVER?
PROPAGATION_NOT_SUPPORTED
1、 PROPAGATION_REQUIRED:
指定的方法必須在事務(wù)內(nèi)執(zhí)行。若當(dāng)前存在事務(wù),就加入到當(dāng)前事務(wù)中; 若當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新事務(wù)。這種傳播行為是最常見(jiàn)的選擇,也是Spring 默認(rèn)的事務(wù)傳播行為。
如該傳播行為加在doOther()方法上。若doSome()方法在調(diào)用doOther() 方法時(shí)就是在事務(wù)內(nèi)運(yùn)行的,則doOther()方法的執(zhí)行也加入到該事務(wù)內(nèi)執(zhí)行。若doSome()方法在調(diào)用 doOther()方法時(shí)沒(méi)有在事務(wù)內(nèi)執(zhí)行,則doOther()方法會(huì)創(chuàng)建一個(gè)事務(wù),并在其中執(zhí)行。

2、PROPAGATION_SUPPORTS
指定的方法支持當(dāng)前事務(wù),但若當(dāng)前沒(méi)有事務(wù),也可以以非事務(wù)方式執(zhí)行。

3、 PROPAGATION_REQUIRES_NEW
總是新建一個(gè)事務(wù),若當(dāng)前存在事務(wù),就將當(dāng)前事務(wù)掛起,直到新事務(wù)執(zhí)行完畢。

C、定義了默認(rèn)事務(wù)超時(shí)時(shí)限
常量TIMEOUT_DEFAULT 定義了事務(wù)底層默認(rèn)的超時(shí)時(shí)限,sql 語(yǔ)句的執(zhí)行時(shí)長(zhǎng)。
注意,事務(wù)的超時(shí)時(shí)限起作用的條件比較多,且超時(shí)的時(shí)間計(jì)算點(diǎn)較復(fù)雜。所以,該值一般就使用默認(rèn)值即可。
程序舉例環(huán)境搭建
舉例:購(gòu)買(mǎi)商品trans_sale 項(xiàng)目
本例要實(shí)現(xiàn)購(gòu)買(mǎi)商品,模擬用戶下訂單,向訂單表添加銷(xiāo)售記錄,從商品表減少庫(kù)存。
實(shí)現(xiàn)步驟:
Step0:創(chuàng)建數(shù)據(jù)庫(kù)表
創(chuàng)建兩個(gè)數(shù)據(jù)庫(kù)表sale , goods sale 銷(xiāo)售表

?goods 商品表

goods 表數(shù)據(jù)

Step1: maven?依 賴 pom.xml


Step2:創(chuàng)建實(shí)體類(lèi)
創(chuàng)建實(shí)體類(lèi) Sale 與Goods

Step3:定義 dao 接口
定義兩個(gè)dao 的接口 SaleDao , GoodsDao

Step4:定義 dao 接口對(duì)應(yīng)的sql 映射文件
SaleDao.xml

GoodsDao.xml

Step5:定義異常類(lèi)
定義service 層可能會(huì)拋出的異常類(lèi)NotEnoughException

Step6:定義 Service 接口
定義 Service 接口BuyGoodsService

Step7:定義 service 的實(shí)現(xiàn)類(lèi)
定義service 層接口的實(shí)現(xiàn)類(lèi) BuyGoodsServiceImpl
1)?類(lèi)定義

2)?Dao?屬性

3)?Buy?方法

Step8:修改 Spring 配置文件內(nèi)容
聲明Mybatis 對(duì)象

聲明業(yè)務(wù)層對(duì)象

Step9:定義測(cè)試類(lèi)
定義測(cè)試類(lèi) MyTest。現(xiàn)在就可以在無(wú)事務(wù)代理的情況下運(yùn)行了。

最后奉上視頻教程??,視頻觀看效果更佳?。∽哌^(guò)路過(guò)別忘素質(zhì)三連哦~~

