首頁 >資料庫 >mysql教程 >如何理解spring事務及聲明式事務的使用

如何理解spring事務及聲明式事務的使用

坏嘻嘻
坏嘻嘻原創
2018-09-15 11:27:081937瀏覽

本篇文章帶給大家的內容是關於如何理解spring事務及聲明式事務的使用,包括數據庫中的事物隔離級別,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

spring事務及聲明式事務的使用

(同學們,開始複習大學還給老師的資料庫知識啦!!)

事務:存取並可能更新資料庫中各種資料項目的一個程式執行單元(unit)。

事務有四個屬性:(ACID)

原子性:一個事務是一個不可分割的工作單元,事務中包含的諸操作要么都做,要么都不做。

一致性;交易必須是使資料庫從一個一致性狀態變成另一個一致性狀態。一致性與原子性使密切相關的。

隔離性:一個交易的執行不能被其他事物幹擾。即一個事務內部操作及使用的資料對並發的其他事物是隔離的,並發執行的各個事務之間不能相互幹擾。

持久性:持久性也稱永久性,指一個交易一旦提交,它對資料庫中資料的改變就應該永久的。

交易目的:為了讓資料保持一致性和完整性。

一致性:一個業務鏈的資料狀態是一致的,不能部分改變部分不改變。

完整性:一個業務鏈的資料是完整的,要麼一起完成一起失敗,不能部分寫入成功,部分寫入失敗。

簡單理解事務的一致性和完整性就是要嘛一起活,要嘛一起死,不能獨活。 (像是淒慘的愛情……^ _ ^)

資料庫中的事物隔離等級

在了解事務隔離等級之前,先來了解資料中經常發生的可能導致業務邏輯失敗的幾種情況。

髒讀

當一個事務正在存取數據,並且對數據進行了修改,並且還沒有提交到資料庫中;這時另一個事務也訪問了這個數據,然後使用了這個數據。

例如:張三的銀行帳戶現在有1000,現在張三存入了200,那麼在張三點擊提交的時候,他媳婦(辛苦的張三在給媳婦存零用錢)在商場購物花了500。張三查看餘額發現只有500了(張三懵逼了。。)。然後兩人為了200吵了起來。以上就是脹讀引起一場家庭大戰。

無法重複讀取

無法重複讀取:一個交易內,多次讀同一個資料。在這個事務還沒結束時,另一個事務也存取了該資料。在第一個事務的兩次讀資料間,由於第二個事務的修改,第一事務兩次讀到的資料可能不一樣。這樣就發生了一個事務內兩次讀到的資料是不一樣的。 (即不能讀到相同的資料)

幻讀

一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行,同時第二個事務向表中插入一行新資料。就會發生操作第一個交易的使用者發現表中還有沒有修改的資料行。就好像發生了幻覺一樣。

spring的五種隔離級別

ISOLATION_DEFAULT

#表示底層資料庫的預設隔離級別,對大部分資料庫而言通常值是:ISOLATION _READ _COMMITTED

#ISOLATION _READ _UNCOMMITTED

表示一個交易可以讀取另一交易修改但還沒有提交的數據,不能防止髒讀和不可重複讀。

ISOLATION _READ _COMMITTED

一個交易只能讀取另一個交易已經提交的數據,可以防止髒讀,但是不能防止不可重複讀。 (大多數情況的建議值)

ISOLATION _REPEATABLE _READ

一個交易在整個過程中可以重複執行某個查詢,並且每次傳回的記錄都相同。即使在多次查詢之間有新增的資料滿足該查詢,這些新增的記錄也會被忽略。可防止髒讀和不可重複讀。

ISOLATION _SERIALIZBLE

所有交易依序逐一執行,這樣交易之間就完全不可能產生幹擾。可防止髒讀,不可重複讀,幻讀。

事務的傳播性(spring提供了七個)

是指事務之間的關係,例如一個事務中含有另一個事務,那麼傳播性用來確定相互的執行。

TransationDefinition.PROPAGETION.REQUIRED

如果目前存在事務,則加入該事務;如果目前沒有事務,則建立一個新的事務。
spring中的預設事務。適合絕大多數情況。

TransationDefinition.PROPAGETION.REQUIRED_NEW

建立一個新的事務,如果目前存在事務,則把目前事務掛起。
意思是創造一個新的事務,和原來的事務沒有任何關係。

TransationDefinition.PROPAGETION.SUPPORTS

如果目前存在事務,則加入該事務;如果目前沒有事務,則以非事務的方式繼續運作。
這種方式很隨意,沒有就沒有,有就有,有點無所謂的態度。

TransationDefinition.PROPAGATION.NOT_SUPPORTED

以非交易的方式運行,如果目前存在事務,則把目前交易掛起。
這種方式非常強硬,沒有就沒有,有也不支持,掛起來,不管它。

TransationDefinition.PROPAGETION_NEVER

#以非交易的方式運行,如果目前存在事務,則拋出例外。
這種方式更加強硬,沒有就沒有,反而報錯,他對大家宣稱:我從不支持事務。

TransationDefinition.PROPAGETION_MANDATORY

如果目前有事務,則加入該交易;如果目前沒有事務,則拋出例外。
這種方式可以說是最強硬的,沒有事務就直接報錯,它對全世界說:我必須要有事務。

TransationDefinition.PROPAGETION_NESTED

如果目前存在事務,則建立一個交易作為目前交易的巢狀事務來運作;如果目前沒有事務,則該取值等價於
TransationDefinition .PROPAGETION_REQUIRED

聲明式交易

使用

#現在來看在springboot中,如果使用宣告式交易:

@Transactional
public void save(Object ob){

}

只要在方法上增加@ Transactional註解方法就可以被事務管理起來。

原始碼

看一下註解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 {};

}

預設值

readOnly : 是否僅僅只讀。預設讀寫都可以

timeout : 交易逾時時間,預設沒有逾時時間

isolation: 交易的隔離等級預設:TransactionDefinition.ISOLATION_DEFAULT(見上文隔離等級)

propagation :交易的傳播屬性預設:TransactionDefinition.PROPAGATION_REQUIRED

#注意事項

  • ##註解應該只應用到public方法上

  • #自呼叫問題:如果類別中沒有註解方法呼叫有註解的方法,那麼外部在呼叫沒有註解的方法時,有註解的方法不會產生交易

以上是如何理解spring事務及聲明式事務的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn