本篇文章帶給大家的內容是關於如何理解spring事務及聲明式事務的使用,包括數據庫中的事物隔離級別,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
(同學們,開始複習大學還給老師的資料庫知識啦!!)
事務:存取並可能更新資料庫中各種資料項目的一個程式執行單元(unit)。
事務有四個屬性:(ACID)
原子性:一個事務是一個不可分割的工作單元,事務中包含的諸操作要么都做,要么都不做。
一致性;交易必須是使資料庫從一個一致性狀態變成另一個一致性狀態。一致性與原子性使密切相關的。
隔離性:一個交易的執行不能被其他事物幹擾。即一個事務內部操作及使用的資料對並發的其他事物是隔離的,並發執行的各個事務之間不能相互幹擾。
持久性:持久性也稱永久性,指一個交易一旦提交,它對資料庫中資料的改變就應該永久的。
交易目的:為了讓資料保持一致性和完整性。
一致性:一個業務鏈的資料狀態是一致的,不能部分改變部分不改變。
完整性:一個業務鏈的資料是完整的,要麼一起完成一起失敗,不能部分寫入成功,部分寫入失敗。
簡單理解事務的一致性和完整性就是要嘛一起活,要嘛一起死,不能獨活。 (像是淒慘的愛情……^ _ ^)
在了解事務隔離等級之前,先來了解資料中經常發生的可能導致業務邏輯失敗的幾種情況。
當一個事務正在存取數據,並且對數據進行了修改,並且還沒有提交到資料庫中;這時另一個事務也訪問了這個數據,然後使用了這個數據。
例如:張三的銀行帳戶現在有1000,現在張三存入了200,那麼在張三點擊提交的時候,他媳婦(辛苦的張三在給媳婦存零用錢)在商場購物花了500。張三查看餘額發現只有500了(張三懵逼了。。)。然後兩人為了200吵了起來。以上就是脹讀引起一場家庭大戰。
無法重複讀取:一個交易內,多次讀同一個資料。在這個事務還沒結束時,另一個事務也存取了該資料。在第一個事務的兩次讀資料間,由於第二個事務的修改,第一事務兩次讀到的資料可能不一樣。這樣就發生了一個事務內兩次讀到的資料是不一樣的。 (即不能讀到相同的資料)
一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行,同時第二個事務向表中插入一行新資料。就會發生操作第一個交易的使用者發現表中還有沒有修改的資料行。就好像發生了幻覺一樣。
#表示底層資料庫的預設隔離級別,對大部分資料庫而言通常值是:ISOLATION _READ _COMMITTED
表示一個交易可以讀取另一交易修改但還沒有提交的數據,不能防止髒讀和不可重複讀。
一個交易只能讀取另一個交易已經提交的數據,可以防止髒讀,但是不能防止不可重複讀。 (大多數情況的建議值)
一個交易在整個過程中可以重複執行某個查詢,並且每次傳回的記錄都相同。即使在多次查詢之間有新增的資料滿足該查詢,這些新增的記錄也會被忽略。可防止髒讀和不可重複讀。
所有交易依序逐一執行,這樣交易之間就完全不可能產生幹擾。可防止髒讀,不可重複讀,幻讀。
是指事務之間的關係,例如一個事務中含有另一個事務,那麼傳播性用來確定相互的執行。
如果目前存在事務,則加入該事務;如果目前沒有事務,則建立一個新的事務。
spring中的預設事務。適合絕大多數情況。
建立一個新的事務,如果目前存在事務,則把目前事務掛起。
意思是創造一個新的事務,和原來的事務沒有任何關係。
如果目前存在事務,則加入該事務;如果目前沒有事務,則以非事務的方式繼續運作。
這種方式很隨意,沒有就沒有,有就有,有點無所謂的態度。
以非交易的方式運行,如果目前存在事務,則把目前交易掛起。
這種方式非常強硬,沒有就沒有,有也不支持,掛起來,不管它。
#以非交易的方式運行,如果目前存在事務,則拋出例外。
這種方式更加強硬,沒有就沒有,反而報錯,他對大家宣稱:我從不支持事務。
如果目前有事務,則加入該交易;如果目前沒有事務,則拋出例外。
這種方式可以說是最強硬的,沒有事務就直接報錯,它對全世界說:我必須要有事務。
如果目前存在事務,則建立一個交易作為目前交易的巢狀事務來運作;如果目前沒有事務,則該取值等價於
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
以上是如何理解spring事務及聲明式事務的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!