Spring事務與數(shù)據(jù)庫事務的交互原理

Spring事務和數(shù)據(jù)庫事務到底是什么關(guān)系?

Spring事務是如何傳遞到數(shù)據(jù)庫的?


首先,我們來回憶一下jdbc這個api,這是java操作數(shù)據(jù)庫的入口,是java操作數(shù)據(jù)庫的通道,是我們與數(shù)據(jù)庫打交道的必經(jīng)之路。那么,是不是說,Spring的事務控制就是通過jdbc傳遞到數(shù)據(jù)庫,然后執(zhí)行的呢?我個人覺得,就是這樣,并且也只有這樣。


繼續(xù)回憶,jdbc怎么操作數(shù)據(jù)庫呢?首先建立連接,然后執(zhí)行增刪改查,然后關(guān)閉數(shù)據(jù)庫連接。如果你需要事務控制,那么就把Connection的自動提交關(guān)閉:

con.setAutoCommit(false);

然后在需要提交事務時顯示提交就可以了。

con.commit();


這就是jdbc操作數(shù)據(jù)庫的方式。


接下來,我們繼續(xù)深入研究一下,應用程序通過jdbc把數(shù)據(jù)庫操作sql發(fā)送到DBMS以后,DBMS如何進行事務控制呢?


這個就是數(shù)據(jù)庫的工作原理了,如果數(shù)據(jù)庫支持事務,那么數(shù)據(jù)庫首先會開啟事務,然后等到所有的sql都執(zhí)行完以后,再提交事務。就像我們在存儲過程中顯式的提交事務一樣。但是數(shù)據(jù)庫如何知道在哪個sql前開啟事務,執(zhí)行到哪里再關(guān)閉事務的呢?這個就是jdbc的實現(xiàn)細節(jié)了,感興趣的可以研究一下jdbc的源代碼。


到這里,我們基本上可以回答開篇提出的疑問了。Spring整合Mybatis的架構(gòu)中,Mybatis是應用程序與數(shù)據(jù)庫通道,是兩者交互的唯一通道。而Mybatis框架封裝的就是jdbc。


接下來,我們還要探討一下,Spring的事務傳播機制與數(shù)據(jù)庫的隔離級別的關(guān)系。

答:二者之間沒有關(guān)系。

Spring的事務傳播機制中的當前事務,指的是當前Spring的事務,還是當前數(shù)據(jù)庫的事務?

spring事務傳播機制如下:

REQUIRED

SUPPORTS

MANDATORY

REQURIED_NEW

NOT_SUPPORTED

NEVER

NESTED


數(shù)據(jù)庫的隔離級別如下:

READ_UNCIMMITED

READ_COMMITED

REPEATABLE_READ

SERIALIZABLE


默認設置是第一種:REQURIED,什么意思呢?就是說,支持當前事務,如果當前沒有事務,就新建一個事務,這是網(wǎng)上的說法,說實話,這個說的有點晦澀難懂,如果不看Spring注解相關(guān)源碼,根本理解不了。


于是乎,我就去看事務的源碼了,看看Spring這個事務傳播機制到底是個什么意思。


源碼沒看懂,先看一下@Transational注解的定義,內(nèi)容還是挺豐富的。主要包含以下屬性:

圖片發(fā)自簡書App


關(guān)于@Transational注解,需要注意以下幾個問題:

注意點: Spring默認情況下會對(RuntimeException)及其子類來進行回滾,在遇見Exception及其子類的時候則不會進行回滾操作。


注意點: @Transactional既可以作用于接口,接口方法上以及類已經(jīng)類的方法上。但是Spring官方不建議接口或者接口方法上使用該注解,因為這只有在使用基于接口的代理時它才會生效。另外, @Transactional 注解應該只被應用到 public 方法上,這是由 Spring AOP 的本質(zhì)決定的。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解,這將被忽略,也不會拋出任何異常。 Spring默認使用的是jdk自帶的基于接口的代理,而沒有使用基于類的代理CGLIB。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容