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)容還是挺豐富的。主要包含以下屬性:

關(guān)于@Transational注解,需要注意以下幾個問題:
注意點: Spring默認情況下會對(RuntimeException)及其子類來進行回滾,在遇見Exception及其子類的時候則不會進行回滾操作。
注意點: @Transactional既可以作用于接口,接口方法上以及類已經(jīng)類的方法上。但是Spring官方不建議接口或者接口方法上使用該注解,因為這只有在使用基于接口的代理時它才會生效。另外, @Transactional 注解應該只被應用到 public 方法上,這是由 Spring AOP 的本質(zhì)決定的。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解,這將被忽略,也不會拋出任何異常。 Spring默認使用的是jdk自帶的基于接口的代理,而沒有使用基于類的代理CGLIB。