本篇內(nèi)容主要講解“Spring事務(wù)管理的詳細(xì)介紹”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Spring事務(wù)管理的詳細(xì)介紹”吧!
成都創(chuàng)新互聯(lián)2013年至今,先為泉州等服務(wù)建站,泉州等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為泉州企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。什么是事務(wù)?
事務(wù)是邏輯上的一組操作,要么都執(zhí)行,要么都不執(zhí)行.
事物的特性(ACID):
原子性: 事務(wù)是最小的執(zhí)行單位,不允許分割。事務(wù)的原子性確保動(dòng)作要么全部完成,要么完全不起作用;
一致性: 執(zhí)行事務(wù)前后,數(shù)據(jù)保持一致;
隔離性: 并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),一個(gè)用戶的事物不被其他事物所干擾,各并發(fā)事務(wù)之間數(shù)據(jù)庫(kù)是獨(dú)立的;
持久性: 一個(gè)事務(wù)被提交之后。它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變是持久的,即使數(shù)據(jù)庫(kù)發(fā)生故障也不應(yīng)該對(duì)其有任何影響。
Spring事務(wù)管理接口:
PlatformTransactionManager: (平臺(tái))事務(wù)管理器
TransactionDefinition: 事務(wù)定義信息(事務(wù)隔離級(jí)別、傳播行為、超時(shí)、只讀、回滾規(guī)則)
TransactionStatus: 事務(wù)運(yùn)行狀態(tài)
所謂事務(wù)管理,其實(shí)就是“按照給定的事務(wù)規(guī)則來(lái)執(zhí)行提交或者回滾操作”。
PlatformTransactionManager接口介紹
Spring并不直接管理事務(wù),而是提供了多種事務(wù)管理器 ,他們將事務(wù)管理的職責(zé)委托給Hibernate或者JTA等持久化機(jī)制所提供的相關(guān)平臺(tái)框架的事務(wù)來(lái)實(shí)現(xiàn)。 Spring事務(wù)管理器的接口是: org.springframework.transaction.PlatformTransactionManager ,通過(guò)這個(gè)接口,Spring為各個(gè)平臺(tái)如JDBC、Hibernate等都提供了對(duì)應(yīng)的事務(wù)管理器,但是具體的實(shí)現(xiàn)就是各個(gè)平臺(tái)自己的事情了。
PlatformTransactionManager接口代碼如下:
PlatformTransactionManager接口中定義了三個(gè)方法:
Public interface PlatformTransactionManager()...{ // Return a currently active transaction or create a new one, according to the specified propagation behavior(根據(jù)指定的傳播行為,返回當(dāng)前活動(dòng)的事務(wù)或創(chuàng)建一個(gè)新事務(wù)。) TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; // Commit the given transaction, with regard to its status(使用事務(wù)目前的狀態(tài)提交事務(wù)) Void commit(TransactionStatus status) throws TransactionException; // Perform a rollback of the given transaction(對(duì)執(zhí)行的事務(wù)進(jìn)行回滾) Void rollback(TransactionStatus status) throws TransactionException; }
我們剛剛也說(shuō)了Spring中PlatformTransactionManager根據(jù)不同持久層框架所對(duì)應(yīng)的接口實(shí)現(xiàn)類,幾個(gè)比較常見(jiàn)的如下圖所示
比如我們?cè)谑褂肑DBC或者iBatis(就是Mybatis)進(jìn)行數(shù)據(jù)持久化操作時(shí),我們的xml配置通常如下:
<!-- 事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 數(shù)據(jù)源 --> <property name="dataSource" ref="dataSource" /> </bean>
TransactionDefinition接口介紹
事務(wù)管理器接口 PlatformTransactionManager 通過(guò) getTransaction(TransactionDefinition definition) 方法來(lái)得到一個(gè)事務(wù),這個(gè)方法里面的參數(shù)是 TransactionDefinition類 ,這個(gè)類就定義了一些基本的事務(wù)屬性。
那么什么是事務(wù)屬性呢?
事務(wù)屬性可以理解成事務(wù)的一些基本配置,描述了事務(wù)策略如何應(yīng)用到方法上。事務(wù)屬性包含了5個(gè)方面。
TransactionDefinition接口中的方法如下:
TransactionDefinition接口中定義了5個(gè)方法以及一些表示事務(wù)屬性的常量比如隔離級(jí)別、傳播行為等等的常量。
我下面只是列出了TransactionDefinition接口中的方法而沒(méi)有給出接口中定義的常量,該接口中的常量信息會(huì)在后面依次介紹到。
public interface TransactionDefinition { // 返回事務(wù)的傳播行為 int getPropagationBehavior(); // 返回事務(wù)的隔離級(jí)別,事務(wù)管理器根據(jù)它來(lái)控制另外一個(gè)事務(wù)可以看到本事務(wù)內(nèi)的哪些數(shù)據(jù) int getIsolationLevel(); // 返回事務(wù)必須在多少秒內(nèi)完成 //返回事務(wù)的名字 String getName(); int getTimeout(); // 返回是否優(yōu)化為只讀事務(wù)。 boolean isReadOnly(); }
(1)事務(wù)隔離級(jí)別(定義了一個(gè)事務(wù)可能受其他并發(fā)事務(wù)影響的程度):
我們先來(lái)看一下 并發(fā)事務(wù)帶來(lái)的問(wèn)題 ,然后再來(lái)介紹一下 TransactionDefinition 接口 中定義了五個(gè)表示隔離級(jí)別的常量。
并發(fā)事務(wù)帶來(lái)的問(wèn)題
在典型的應(yīng)用程序中,多個(gè)事務(wù)并發(fā)運(yùn)行,經(jīng)常會(huì)操作相同的數(shù)據(jù)來(lái)完成各自的任務(wù)(多個(gè)用戶對(duì)統(tǒng)一數(shù)據(jù)進(jìn)行操作)。并發(fā)雖然是必須的,但可能會(huì)導(dǎo)致一下的問(wèn)題。
臟讀(Dirty read): 當(dāng)一個(gè)事務(wù)正在訪問(wèn)數(shù)據(jù)并且對(duì)數(shù)據(jù)進(jìn)行了修改,而這種修改還沒(méi)有提交到數(shù)據(jù)庫(kù)中,這時(shí)另外一個(gè)事務(wù)也訪問(wèn)了這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。因?yàn)檫@個(gè)數(shù)據(jù)是還沒(méi)有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是“臟數(shù)據(jù)”,依據(jù)“臟數(shù)據(jù)”所做的操作可能是不正確的。
丟失修改(Lost to modify): 指在一個(gè)事務(wù)讀取一個(gè)數(shù)據(jù)時(shí),另外一個(gè)事務(wù)也訪問(wèn)了該數(shù)據(jù),那么在第一個(gè)事務(wù)中修改了這個(gè)數(shù)據(jù)后,第二個(gè)事務(wù)也修改了這個(gè)數(shù)據(jù)。這樣第一個(gè)事務(wù)內(nèi)的修改結(jié)果就被丟失,因此稱為丟失修改。
例如:事務(wù)1讀取某表中的數(shù)據(jù)A=20,事務(wù)2也讀取A=20,事務(wù)1修改A=A-1,事務(wù)2也修改A=A-1,最終結(jié)果A=19,事務(wù)1的修改被丟失。
不可重復(fù)讀(Unrepeatableread): 指在一個(gè)事務(wù)內(nèi)多次讀同一數(shù)據(jù)。在這個(gè)事務(wù)還沒(méi)有結(jié)束時(shí),另一個(gè)事務(wù)也訪問(wèn)該數(shù)據(jù)。那么,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個(gè)事務(wù)的修改導(dǎo)致第一個(gè)事務(wù)兩次讀取的數(shù)據(jù)可能不太一樣。這就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的情況,因此稱為不可重復(fù)讀。
幻讀(Phantom read): 幻讀與不可重復(fù)讀類似。它發(fā)生在一個(gè)事務(wù)(T1)讀取了幾行數(shù)據(jù),接著另一個(gè)并發(fā)事務(wù)(T2)插入了一些數(shù)據(jù)時(shí)。在隨后的查詢中,第一個(gè)事務(wù)(T1)就會(huì)發(fā)現(xiàn)多了一些原本不存在的記錄,就好像發(fā)生了幻覺(jué)一樣,所以稱為幻讀。
不可重復(fù)度和幻讀區(qū)別:
不可重復(fù)讀的重點(diǎn)是修改,幻讀的重點(diǎn)在于新增或者刪除。
例1(同樣的條件, 你讀取過(guò)的數(shù)據(jù), 再次讀取出來(lái)發(fā)現(xiàn)值不一樣了 ):事務(wù)1中的A先生讀取自己的工資為 1000的操作還沒(méi)完成,事務(wù)2中的B先生就修改了A的工資為2000,導(dǎo) 致A再讀自己的工資時(shí)工資變?yōu)?2000;這就是不可重復(fù)讀。
例2(同樣的條件, 第1次和第2次讀出來(lái)的記錄數(shù)不一樣 ):假某工資單表中工資大于3000的有4人,事務(wù)1讀取了所有工資大于3000的人,共查到4條記錄,這時(shí)事務(wù)2 又插入了一條工資大于3000的記錄,事務(wù)1再次讀取時(shí)查到的記錄就變?yōu)榱?條,這樣就導(dǎo)致了幻讀。
隔離級(jí)別
TransactionDefinition 接口中定義了五個(gè)表示隔離級(jí)別的常量:
TransactionDefinition.ISOLATION_DEFAULT:使用后端數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別,Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級(jí)別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級(jí)別.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級(jí)別,允許讀取尚未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀、幻讀或不可重復(fù)讀
TransactionDefinition.ISOLATION_READ_COMMITTED: 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
TransactionDefinition.ISOLATION_REPEATABLE_READ: 對(duì)同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生。
TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級(jí)別,完全服從ACID的隔離級(jí)別。所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說(shuō),該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會(huì)用到該級(jí)別。
(2)事務(wù)傳播行為(為了解決業(yè)務(wù)層方法之間互相調(diào)用的事務(wù)問(wèn)題):
當(dāng)事務(wù)方法被另一個(gè)事務(wù)方法調(diào)用時(shí),必須指定事務(wù)應(yīng)該如何傳播。例如:方法可能繼續(xù)在現(xiàn)有事務(wù)中運(yùn)行,也可能開(kāi)啟一個(gè)新事務(wù),并在自己的事務(wù)中運(yùn)行。在TransactionDefinition定義中包括了如下幾個(gè)表示傳播行為的常量:
支持當(dāng)前事務(wù)的情況:
TransactionDefinition.PROPAGATION_REQUIRED: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)。
TransactionDefinition.PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則以非事務(wù)的方式繼續(xù)運(yùn)行。
TransactionDefinition.PROPAGATION_MANDATORY: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒(méi)有事務(wù),則拋出異常。(mandatory:強(qiáng)制性)
不支持當(dāng)前事務(wù)的情況:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_NEVER: 以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),則拋出異常。
其他情況:
TransactionDefinition.PROPAGATION_NESTED: 如果當(dāng)前存在事務(wù),則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來(lái)運(yùn)行;如果當(dāng)前沒(méi)有事務(wù),則該取值等價(jià)于TransactionDefinition.PROPAGATION_REQUIRED。
這里需要指出的是,前面的六種事務(wù)傳播行為是 Spring 從 EJB 中引入的,他們共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 啟動(dòng)的事務(wù)內(nèi)嵌于外部事務(wù)中(如果存在外部事務(wù)的話),此時(shí),內(nèi)嵌事務(wù)并不是一個(gè)獨(dú)立的事務(wù),它依賴于外部事務(wù)的存在,只有通過(guò)外部的事務(wù)提交,才能引起內(nèi)部事務(wù)的提交,嵌套的子事務(wù)不能單獨(dú)提交。如果熟悉 JDBC 中的保存點(diǎn)(SavePoint)的概念,那嵌套事務(wù)就很容易理解了,其實(shí)嵌套的子事務(wù)就是保存點(diǎn)的一個(gè)應(yīng)用,一個(gè)事務(wù)中可以包括多個(gè)保存點(diǎn),每一個(gè)嵌套子事務(wù)。另外,外部事務(wù)的回滾也會(huì)導(dǎo)致嵌套子事務(wù)的回滾。
(3) 事務(wù)超時(shí)屬性(一個(gè)事務(wù)允許執(zhí)行的最長(zhǎng)時(shí)間)
所謂事務(wù)超時(shí),就是指一個(gè)事務(wù)所允許執(zhí)行的最長(zhǎng)時(shí)間,如果超過(guò)該時(shí)間限制但事務(wù)還沒(méi)有完成,則自動(dòng)回滾事務(wù)。在 TransactionDefinition 中以 int 的值來(lái)表示超時(shí)時(shí)間,其單位是秒。
(4) 事務(wù)只讀屬性(對(duì)事物資源是否執(zhí)行只讀操作)
事務(wù)的只讀屬性是指,對(duì)事務(wù)性資源進(jìn)行只讀操作或者是讀寫(xiě)操作。所謂事務(wù)性資源就是指那些被事務(wù)管理的資源,比如數(shù)據(jù)源、 JMS 資源,以及自定義的事務(wù)性資源等等。如果確定只對(duì)事務(wù)性資源進(jìn)行只讀操作,那么我們可以將事務(wù)標(biāo)志為只讀的,以提高事務(wù)處理的性能。在 TransactionDefinition 中以 boolean 類型來(lái)表示該事務(wù)是否只讀。
(5) 回滾規(guī)則(定義事務(wù)回滾規(guī)則)
這些規(guī)則定義了哪些異常會(huì)導(dǎo)致事務(wù)回滾而哪些不會(huì)。默認(rèn)情況下,事務(wù)只有遇到運(yùn)行期異常時(shí)才會(huì)回滾,而在遇到檢查型異常時(shí)不會(huì)回滾(這一行為與EJB的回滾行為是一致的)。 但是你可以聲明事務(wù)在遇到特定的檢查型異常時(shí)像遇到運(yùn)行期異常那樣回滾。同樣,你還可以聲明事務(wù)遇到特定的異常不回滾,即使這些異常是運(yùn)行期異常。
TransactionStatus接口介紹
TransactionStatus接口用來(lái)記錄事務(wù)的狀態(tài) 該接口定義了一組方法,用來(lái)獲取或判斷事務(wù)的相應(yīng)狀態(tài)信息.
PlatformTransactionManager.getTransaction(…) 方法返回一個(gè) TransactionStatus 對(duì)象。返回的TransactionStatus 對(duì)象可能代表一個(gè)新的或已經(jīng)存在的事務(wù)(如果在當(dāng)前調(diào)用堆棧有一個(gè)符合條件的事務(wù))。
TransactionStatus接口接口內(nèi)容如下:
public interface TransactionStatus{ boolean isNewTransaction(); // 是否是新的事物 boolean hasSavepoint(); // 是否有恢復(fù)點(diǎn) void setRollbackOnly(); // 設(shè)置為只回滾 boolean isRollbackOnly(); // 是否為只回滾 boolean isCompleted; // 是否已完成 }
到此,相信大家對(duì)“Spring事務(wù)管理的詳細(xì)介紹”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)建站網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
網(wǎng)頁(yè)題目:Spring事務(wù)管理的詳細(xì)介紹-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://chinadenli.net/article40/cdjjeo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、小程序開(kāi)發(fā)、移動(dòng)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、網(wǎng)站維護(hù)、軟件開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容