實現事務必須滿足以下四大特性:
隔離性 通過mvvc實現(相對應的有mvcc)
原子性、一致性、永續性:通過資料庫的redo log、undo log、force log at commit實現
資料庫是可以控制事務的傳播和隔離級別的,spring在之上又進一步做了封裝,本質上是同一概念。
事務的四大特性之一:隔離性 ,隔離性在資料庫事務中有四種級別。
而spring則在其基礎上加了一種default,這是platfromtransactionmanager預設的隔離級別,使用資料庫預設的事務隔離級別。
其他四種隔離級別如下:
假設有兩個事務交替執行,分別為事務a、事務b
事務a做了資料的更改,而事務b能看到事務a未提交的更新資料;
這種隔離級別可能會產生髒讀,比如事務a把資料更改撤銷了。
事務a做了資料的更改,事務b只有等事務a提交更改資料後,才能讀到新資料。
這種隔離級別可能會產生不可重複讀,比如事務b在事務a提交前讀第一次,提交後讀第二次,讀到的資料可能不一致。
可重複讀是mysql innodb預設隔離級別。
事務b開始了事務,不管事務a是否提交修改的資料,事務b多次讀到的資料都是原先一致。
這種隔離級別可能會產生幻讀,比如註解為id的資料:
事務a:select * from users where id = 1; //先看看id是否存在
事務b:insert into users(id, name) values (1, '事務b擁有'); //事務b占用了id=1
事務a:insert into users(id, name) values (1, '事務a擁有'); //事務a繼續查id=1,還是空的,但是執行插入報錯
事務a發生了幻讀,讀的是鬼影。(這裡容易混淆,不可重複讀側重表達 讀-讀,幻讀側重表達 讀-寫)
對事務a讀取到的資料進行加鎖,事務b無法對該資料做修改操作,會阻塞住。只有等a事務提交事務後,修改操作才會執行。
隔離級別越高,對併發的影響就越大。可序列化容易導致超時和鎖爭用問題。
在spring種,通過@transactional
註解的isolation屬性,就可以設定當前方法的事務級別
spring在開啟事務時,會對當前會話設定事務隔離級別;所以當spring設定的隔離級別和資料庫的隔離級別不一致,spring的隔離級別會生效。
spring通過 aop環繞通知進行攔截 來實現事務,我們不需要關心事務的開始、提交、回滾,只需要在方法上新增@transactional
註解就可以了。
但是帶事務的方法a呼叫普通方法b,算不算同乙個事務呢?異常了是否會一起回滾呢?諸如此類問題,事務傳播機制就能解決。
通過@transactional
註解的propagation=propagation.***x
屬性,就可以設定事務傳播機制。機制類別有以下:
假設 方法a 呼叫了 方法b
myisam不支援事務,需要事務的一般用innodb引擎
資料來源沒有配置事務管理器
@transactional
註解只能新增到public方法上
需要丟擲異常,事務才能回滾
預設捕捉的是runtimeexception,而丟擲的為exception
只有在外部呼叫事務才會生效
乙個普通方法呼叫乙個事務方法
乙個事務方法呼叫另乙個事務方法
解決方式就是改為外部呼叫,拆成兩個service
如果非要在內部呼叫,可以使用**物件去呼叫
spring再學習(二) spring事務
與關係型資料庫一致,事務都遵循 acid 原則 spring支援程式設計式事務管理以及宣告式事務管理兩種方式。在spring框架,用註解開啟事務 transactional,當然事務有其特性 spring事務的傳播行為有7種 spring在事務中使用isolation來配置它 isolation r...
Spring 框架(二) 事務
spring 宣告式事務讓我們從複雜的事務處理中得到解脫。使得我們再也無需去處理獲得連線,關閉連線,事務提交和回滾等這些操作。我們在使用 spring 宣告式事務時,有乙個非常重要的概念就是事務屬性。它由事務傳播行為,隔離級別,事務的超時值和事務唯讀標誌組成。spring 的 transaction...
Spring事務(一) Spring事務的使用
事務的經典舉例 某人要在商店使用電子貨幣購買100元的東西,當中至少包括兩個操作 該人賬戶減少100元 商店賬戶增加100元 事務就是要確保以上兩個操作 都能完成 或者 一起取消,否則就會出現100元平白消失或出現的情況。摘自wiki spring事務有兩種方式 程式設計式事務管理 宣告式事務管理 ...