Spring事務和數據庫事務到底是什么關系?
Spring事務是如何傳遞到數據庫的适袜?
首先柄错,我們來回憶一下jdbc這個api,這是java操作數據庫的入口痪蝇,是java操作數據庫的通道鄙陡,是我們與數據庫打交道的必經之路。那么躏啰,是不是說趁矾,Spring的事務控制就是通過jdbc傳遞到數據庫,然后執(zhí)行的呢?我個人覺得皿桑,就是這樣,并且也只有這樣截酷。
繼續(xù)回憶蔓同,jdbc怎么操作數據庫呢饶辙?首先建立連接,然后執(zhí)行增刪改查斑粱,然后關閉數據庫連接弃揽。如果你需要事務控制,那么就把Connection的自動提交關閉:
con.setAutoCommit(false);
然后在需要提交事務時顯示提交就可以了则北。
con.commit();
這就是jdbc操作數據庫的方式矿微。
接下來,我們繼續(xù)深入研究一下尚揣,應用程序通過jdbc把數據庫操作sql發(fā)送到DBMS以后涌矢,DBMS如何進行事務控制呢?
這個就是數據庫的工作原理了快骗,如果數據庫支持事務娜庇,那么數據庫首先會開啟事務,然后等到所有的sql都執(zhí)行完以后方篮,再提交事務名秀。就像我們在存儲過程中顯式的提交事務一樣。但是數據庫如何知道在哪個sql前開啟事務藕溅,執(zhí)行到哪里再關閉事務的呢泰偿?這個就是jdbc的實現細節(jié)了,感興趣的可以研究一下jdbc的源代碼蜈垮。
到這里耗跛,我們基本上可以回答開篇提出的疑問了。Spring整合Mybatis的架構中攒发,Mybatis是應用程序與數據庫通道调塌,是兩者交互的唯一通道。而Mybatis框架封裝的就是jdbc惠猿。
接下來羔砾,我們還要探討一下,Spring的事務傳播機制與數據庫的隔離級別的關系偶妖。
答:二者之間沒有關系姜凄。
Spring的事務傳播機制中的當前事務,指的是當前Spring的事務趾访,還是當前數據庫的事務态秧?
spring事務傳播機制如下:
REQUIRED
SUPPORTS
MANDATORY
REQURIED_NEW
NOT_SUPPORTED
NEVER
NESTED
數據庫的隔離級別如下:
READ_UNCIMMITED
READ_COMMITED
REPEATABLE_READ
SERIALIZABLE
默認設置是第一種:REQURIED,什么意思呢扼鞋?就是說申鱼,支持當前事務愤诱,如果當前沒有事務,就新建一個事務捐友,這是網上的說法淫半,說實話,這個說的有點晦澀難懂匣砖,如果不看Spring注解相關源碼科吭,根本理解不了。
于是乎猴鲫,我就去看事務的源碼了砌溺,看看Spring這個事務傳播機制到底是個什么意思。
源碼沒看懂变隔,先看一下@Transational注解的定義,內容還是挺豐富的蟹倾。主要包含以下屬性:
關于@Transational注解匣缘,需要注意以下幾個問題:
注意點: Spring默認情況下會對(RuntimeException)及其子類來進行回滾,在遇見Exception及其子類的時候則不會進行回滾操作鲜棠。
注意點: @Transactional既可以作用于接口肌厨,接口方法上以及類已經類的方法上。但是Spring官方不建議接口或者接口方法上使用該注解豁陆,因為這只有在使用基于接口的代理時它才會生效柑爸。另外, @Transactional 注解應該只被應用到 public 方法上盒音,這是由 Spring AOP 的本質決定的表鳍。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解祥诽,這將被忽略譬圣,也不會拋出任何異常。 Spring默認使用的是jdk自帶的基于接口的代理雄坪,而沒有使用基于類的代理CGLIB厘熟。