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

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

(同窗們,開始複習大學還給老師的數據庫知識啦!!)spring

事務:訪問並可能更新數據庫中各類數據項的一個程序執行單元(unit)。

事務有四個屬性:(ACID)數據庫

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

一致性;事務必須是使數據庫從一個一致性狀態變到另外一個一致性狀態。一致性與原子性使密切相關的。微信

隔離性:一個事務的執行不能被其餘事物干擾。即一個事務內部操做及使用的數據對併發的其餘事物是隔離的,併發執行的各個事務之間不能相互干擾。併發

持久性:持久性也稱永久性,指一個事務一旦提交,它對數據庫中數據的改變就應該永久的。spa

事務目的:爲了使數據保持一致性和完整性。code

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

完整性:一個業務鏈的數據是完整的,要麼一塊兒完成一塊兒失敗,不能部分寫入成功,部分寫入失敗。rem

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

數據庫中的事物隔離級別

在瞭解事務隔離級別以前,先來了解一下數據中常常發生的可能致使業務邏輯失敗的幾種狀況。

髒讀

當一個事務正在訪問數據,而且對數據進行了修改,而且尚未提交到數據庫中;這時另外一事務也訪問了這個數據,而後使用了這個數據。

例如:張三的銀行帳戶如今有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方法上
  • 自調用問題:若是類中沒有註解方法調用有註解的方法,那麼外部在調用沒有註解的方法時,有註解的方法不會產生事務。

關注個人公衆號第一時間閱讀有趣的技術故事
掃碼關注:

也能夠在微信搜索公衆號便可關注我:codexiulian 渴望與你一塊兒成長進步!

相關文章
相關標籤/搜索