spring事務(wù)及聲明式事務(wù)的使用
(同學(xué)們性芬,開(kāi)始復(fù)習(xí)大學(xué)還給老師的數(shù)據(jù)庫(kù)知識(shí)啦M摹!)
事務(wù):訪問(wèn)并可能更新數(shù)據(jù)庫(kù)中各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)行單元(unit)髓迎。
事務(wù)有四個(gè)屬性:(ACID)
原子性:一個(gè)事務(wù)是一個(gè)不可分割的工作單元旱易,事務(wù)中包括的諸操作要么都做禁偎,要么都不做。
一致性咒唆;事務(wù)必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)届垫。一致性與原子性使密切相關(guān)的释液。
隔離性:一個(gè)事務(wù)的執(zhí)行不能被其他事物干擾全释。即一個(gè)事務(wù)內(nèi)部操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事物是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能相互干擾误债。
持久性:持久性也稱永久性浸船,指一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就應(yīng)該永久的寝蹈。
事務(wù)目的:為了使數(shù)據(jù)保持一致性和完整性李命。
一致性:一個(gè)業(yè)務(wù)鏈的數(shù)據(jù)狀態(tài)是一致的,不能部分改變部分不改變箫老。
完整性:一個(gè)業(yè)務(wù)鏈的數(shù)據(jù)是完整的封字,要么一起完成一起失敗,不能部分寫入成功耍鬓,部分寫入失敗阔籽。
簡(jiǎn)單理解事務(wù)的一致性和完整性就是要么一起活,要么一起死牲蜀,不能獨(dú)活笆制。(像是凄慘的愛(ài)情…………^?_?^)
數(shù)據(jù)庫(kù)中的事物隔離級(jí)別
在了解事務(wù)隔離級(jí)別之前,先來(lái)了解一下數(shù)據(jù)中經(jīng)常發(fā)生的可能導(dǎo)致業(yè)務(wù)邏輯失敗的幾種情況涣达。
臟讀
當(dāng)一個(gè)事務(wù)正在訪問(wèn)數(shù)據(jù)在辆,并且對(duì)數(shù)據(jù)進(jìn)行了修改,并且還沒(méi)有提交到數(shù)據(jù)庫(kù)中度苔;這時(shí)另一事務(wù)也訪問(wèn)了這個(gè)數(shù)據(jù)匆篓,然后使用了這個(gè)數(shù)據(jù)。
例如:張三的銀行賬戶現(xiàn)在有1000寇窑,現(xiàn)在張三存入了200鸦概,那么在張三點(diǎn)擊提交的時(shí)候,他媳婦(辛苦的張三在給媳婦存零花錢)在商場(chǎng)購(gòu)物花了500疗认。張三查看余額發(fā)現(xiàn)只有500了(張三懵逼了完残。伏钠。)。然后兩人為了200吵了起來(lái)谨设。以上就是脹讀引起一場(chǎng)家庭大戰(zhàn)熟掂。
不可重復(fù)讀
不可重復(fù)讀:一個(gè)事務(wù)內(nèi),多次讀同一個(gè)數(shù)據(jù)扎拣。在這個(gè)事務(wù)還沒(méi)有結(jié)束時(shí)赴肚,另一個(gè)事務(wù)也訪問(wèn)了該數(shù)據(jù)。在第一個(gè)事務(wù)的兩次讀數(shù)據(jù)間二蓝,由于第二個(gè)事務(wù)的修改誉券,第一事務(wù)兩次讀到的數(shù)據(jù)可能不一樣。這樣就發(fā)生了一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的刊愚。(即不能讀到相同的數(shù)據(jù))
幻讀
一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改踊跟,這種修改涉及到表中的全部數(shù)據(jù)行,與此同時(shí)第二個(gè)事務(wù)向表中插入一行新數(shù)據(jù)鸥诽。就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒(méi)有修改的數(shù)據(jù)行商玫。就好像發(fā)生了幻覺(jué)一樣。
spring的五種隔離級(jí)別
ISOLATION_DEFAULT
表示底層數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別牡借,對(duì)大部分?jǐn)?shù)據(jù)庫(kù)而言通常值是:ISOLATION _READ _COMMITTED
ISOLATION _READ _UNCOMMITTED
表示一個(gè)事務(wù)可以讀取另一事務(wù)修改但還沒(méi)有提交的數(shù)據(jù)拳昌,不能防止臟讀和不可重復(fù)讀。
ISOLATION _READ _COMMITTED
一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)钠龙,可以防止臟讀炬藤,但是不能防止不可重復(fù)讀。(大多數(shù)情況的推薦值)
ISOLATION _REPEATABLE _READ
一個(gè)事務(wù)在整個(gè)過(guò)程中可以多次重復(fù)執(zhí)行某個(gè)查詢碴里,并且每次返回的記錄都相同沈矿。即使在多次查詢之間有新增的數(shù)據(jù)滿足該查詢,這些新增的記錄也會(huì)被忽略并闲∠杆可以防止臟讀和不可重復(fù)讀。
ISOLATION _SERIALIZBLE
所有事務(wù)依次逐個(gè)執(zhí)行帝火,這樣事務(wù)之間就完全不可能產(chǎn)生干擾溜徙。可以防止臟讀犀填,不可重復(fù)讀蠢壹,幻讀。
事務(wù)的傳播性(spring提供了七個(gè))
是指事務(wù)之間的關(guān)系九巡,例如一個(gè)事務(wù)中含有另一個(gè)事務(wù)图贸,那么傳播性用來(lái)確定相互的執(zhí)行。
TransationDefinition.PROPAGETION.REQUIRED
如果當(dāng)前存在事務(wù),則加入該事務(wù)疏日;如果當(dāng)前沒(méi)有事務(wù)偿洁,則創(chuàng)建一個(gè)新的事務(wù)。
spring中的默認(rèn)事務(wù)沟优。適合絕大多數(shù)情況涕滋。
TransationDefinition.PROPAGETION.REQUIRED_NEW
創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù)挠阁,則把當(dāng)前事務(wù)掛起宾肺。
意思是創(chuàng)建一個(gè)新的事務(wù),和原來(lái)的事務(wù)沒(méi)有任何關(guān)系侵俗。
TransationDefinition.PROPAGETION.SUPPORTS
如果當(dāng)前存在事務(wù)锨用,則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù)隘谣,則以非事務(wù)的方式繼續(xù)運(yùn)行增拥。
這種方式非常隨意,沒(méi)有就沒(méi)有洪橘,有就有跪者,有點(diǎn)無(wú)所謂的態(tài)度棵帽。
TransationDefinition.PROPAGATION.NOT_SUPPORTED
以非事務(wù)的方式運(yùn)行熄求,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起逗概。
這種方式非常強(qiáng)硬弟晚,沒(méi)有就沒(méi)有,有也不支持逾苫,掛起來(lái)卿城,不管它。
TransationDefinition.PROPAGETION_NEVER
以非事務(wù)的方式運(yùn)行铅搓,如果當(dāng)前存在事務(wù)瑟押,則拋出異常。
這種方式更加強(qiáng)硬星掰,沒(méi)有就沒(méi)有多望,有反而報(bào)錯(cuò),他對(duì)大家宣稱:我從不支持事務(wù)氢烘。
TransationDefinition.PROPAGETION_MANDATORY
如果當(dāng)前存在事務(wù)怀偷,則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù)播玖,則拋出異常椎工。
這種方式可以說(shuō)是最強(qiáng)硬的,沒(méi)有事務(wù)就直接報(bào)錯(cuò),它對(duì)全世界說(shuō):我必須要有事務(wù)维蒙。
TransationDefinition.PROPAGETION_NESTED
如果當(dāng)前存在事務(wù)掰吕,則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來(lái)運(yùn)行;如果當(dāng)前沒(méi)有事務(wù)颅痊,則該取值等價(jià)于
TransationDefinition.PROPAGETION_REQUIRED
聲明式事務(wù)
使用
現(xiàn)在來(lái)看在springboot中畴栖,如果使用聲明式事務(wù):
@Transactional
public void save(Object ob){
}
只要在方法上增加@Transactional注解方法就可以被事務(wù)管理起來(lái)。
源碼
看一下注解Transactional的源碼:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
默認(rèn)值
readOnly : 是否僅僅只讀八千。默認(rèn)讀寫都可以
timeout : 事務(wù)超時(shí)時(shí)間吗讶,默認(rèn)沒(méi)有超時(shí)時(shí)間
isolation: 事務(wù)的隔離級(jí)別 默認(rèn):TransactionDefinition.ISOLATION_DEFAULT(見(jiàn)上文隔離級(jí)別)
propagation :事務(wù)的傳播屬性 默認(rèn):TransactionDefinition.PROPAGATION_REQUIRED
注意事項(xiàng)
注解應(yīng)該只被應(yīng)用到public方法上
自調(diào)用問(wèn)題:如果類中沒(méi)有注解方法調(diào)用有注解的方法,那么外部在調(diào)用沒(méi)有注解的方法時(shí)恋捆,有注解的方法不會(huì)產(chǎn)生事務(wù)照皆。
關(guān)注我的公眾號(hào)第一時(shí)間閱讀有趣的技術(shù)故事
掃碼關(guān)注:
也可以在微信搜索公眾號(hào)即可關(guān)注我:codexiulian
渴望與你一起成長(zhǎng)進(jìn)步!