溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Spring聲明式事務(wù)@Transactional知識(shí)點(diǎn)有哪些

發(fā)布時(shí)間:2021-08-05 09:37:42 來(lái)源:億速云 閱讀:161 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹了Spring聲明式事務(wù)@Transactional知識(shí)點(diǎn)有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

@Transactional注解支持9個(gè)屬性的設(shè)置,這里只講解其中使用較多的三個(gè)屬性:readOnly、propagation、isolation。其中propagation屬性用來(lái)枚舉事務(wù)的傳播行為,isolation用來(lái)設(shè)置事務(wù)隔離級(jí)別,readOnly進(jìn)行讀寫(xiě)事務(wù)控制。

@Service
@Transactional(readOnly = true)
public class AppTradeRec2Service extends BaseService {
 @Autowired
 private AppTradeRecDao appTradeRecDao;
 @Autowired
 private ConsInfoDao consInfoDao;
 
 @Transactional(readOnly = false)
 public void payCharge(TradeRec tradeRec) {
 User usr = UserUtils.getUser();
 ConsInfo cons = consInfoDao.getByUser(usr.getId());
 //修改交易記錄
 tradeRec.setPayBefore(cons.getAccountAmt());
 tradeRec.setPayAfter(cons.getAccountAmt() - tradeRec.getRcvAmt());
 tradeRec.setIsPay("99");
 appTradeRecDao.save(tradeRec);
 //修改賬戶(hù)余額
 cons.setAccountAmt(cons.getAccountAmt() - tradeRec.getRcvAmt());
 consInfoDao.save(cons);
 }
}

一、readOnly讀寫(xiě)事務(wù)控制

readOnly=true表明所注解的方法或類(lèi)只是讀取數(shù)據(jù)。

readOnly=false表明所注解的方法或類(lèi)是增加,刪除,修改數(shù)據(jù)。

二、isolation事務(wù)隔離級(jí)別

我們?cè)谑褂檬聞?wù)過(guò)程中,通常會(huì)發(fā)生以下三種情況:

1、臟讀(dirty read):當(dāng)一個(gè)事務(wù)讀取另一個(gè)事務(wù)尚未提交的修改時(shí),產(chǎn)生臟讀。

2、不可重復(fù)讀(non-repeatable read):同一查詢(xún)?cè)谕皇聞?wù)中多次進(jìn)行,由于其他提交事務(wù)所做的修改或刪除,每次返回不同的結(jié)果集,此時(shí)發(fā)生非重復(fù)讀。

3、幻像讀(phantom read):同一查詢(xún)?cè)谕皇聞?wù)中多次進(jìn)行,由于其他提交事務(wù)所做的插入操作,每次返回不同的結(jié)果集,此時(shí)發(fā)生幻像讀。

針對(duì)上述三種情況,Spring提供了5種事務(wù)隔離級(jí)別予以解決:

1、DEFAULT默認(rèn)級(jí)別

DEFAULT為數(shù)據(jù)源(數(shù)據(jù)庫(kù))的默認(rèn)隔離級(jí)別,以目前常用的MySQL為例,默認(rèn)的隔離級(jí)別通常為REPEATABLE_READ。

2、READ_UNCOMMITTED未授權(quán)讀取級(jí)別

這是最低的隔離級(jí)別,一個(gè)事務(wù)能讀取到別的事務(wù)未提交的更新數(shù)據(jù),很不安全,可能出現(xiàn)丟失更新、臟讀、不可重復(fù)讀、幻讀。

3、READ_COMMITTED授權(quán)讀取級(jí)別

以操作同一行數(shù)據(jù)為前提,讀事務(wù)允許其他讀事務(wù)和寫(xiě)事務(wù),未提交的寫(xiě)事務(wù)禁止其他讀事務(wù)和寫(xiě)事務(wù)。此隔離級(jí)別可以防止更新丟失、臟讀,但不能防止不可重復(fù)讀、幻讀。此隔離級(jí)別可以通過(guò)“瞬間共享讀鎖”和“排他寫(xiě)鎖”實(shí)現(xiàn)。

4、REPEATABLE_READ可重復(fù)讀取級(jí)別

保證同一事務(wù)中先后執(zhí)行的多次查詢(xún)將返回同一結(jié)果,不受其他事務(wù)影響。以操作同一行數(shù)據(jù)為前提,讀事務(wù)禁止其他寫(xiě)事務(wù),但允許其他讀事務(wù),未提交的寫(xiě)事務(wù)禁止其他讀事務(wù)和寫(xiě)事務(wù)。此隔離級(jí)別可以防止更新丟失、臟讀、不可重復(fù)讀,但不能防止幻讀。

5、SERIALIZABLE序列化級(jí)別

所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾。提供嚴(yán)格的事務(wù)隔離,此隔離級(jí)別可以防止更新丟失、臟讀、不可重復(fù)讀、幻讀。如果僅僅通過(guò)“行級(jí)鎖”是無(wú)法實(shí)現(xiàn)事務(wù)序列化的,必須通過(guò)其他機(jī)制保證新插入的數(shù)據(jù)不會(huì)被剛執(zhí)行查詢(xún)操作的事務(wù)訪(fǎng)問(wèn)到。

隔離級(jí)別越高,越能保證數(shù)據(jù)的完整性和一致性,但是對(duì)并發(fā)性能的影響也越大。對(duì)于多數(shù)應(yīng)用程序,可以?xún)?yōu)先考慮把數(shù)據(jù)庫(kù)系統(tǒng)的隔離級(jí)別設(shè)為Read Committed。它能夠避免更新丟失、臟讀,而且具有較好的并發(fā)性能。盡管它會(huì)導(dǎo)致不可重復(fù)讀、幻讀這些并發(fā)問(wèn)題,在可能出現(xiàn)這類(lèi)問(wèn)題的個(gè)別場(chǎng)合,可以由應(yīng)用程序采用悲觀(guān)鎖或樂(lè)觀(guān)鎖來(lái)控制。

三、Propagation事務(wù)傳播行為

Propagation屬性用來(lái)枚舉事務(wù)的傳播行為。所謂事務(wù)傳播行為就是多個(gè)事務(wù)方法相互調(diào)用時(shí),事務(wù)如何在這些方法間傳播。Spring支持7種事務(wù)傳播行為,默認(rèn)為REQUIRED。

1、REQUIRED

REQUIRED是常用的事務(wù)傳播行為,如果當(dāng)前沒(méi)有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。

2、SUPPORTS

SUPPORTS表示當(dāng)前方法不需要事務(wù)上下文,但是如果存在當(dāng)前事務(wù)的話(huà),那么這個(gè)方法會(huì)在這個(gè)事務(wù)中運(yùn)行。

3、MANDATORY

MANDATORY表示該方法必須在事務(wù)中運(yùn)行,如果當(dāng)前事務(wù)不存在,則會(huì)拋出一個(gè)異常。不會(huì)主動(dòng)開(kāi)啟一個(gè)事務(wù)。

4、REQUIRES_NEW

REQUIRES_NEW表示當(dāng)前方法必須運(yùn)行在它自己的事務(wù)中。一個(gè)新的事務(wù)將被啟動(dòng),如果存在當(dāng)前事務(wù),在該方法執(zhí)行期間,當(dāng)前事務(wù)會(huì)被掛起(如果一個(gè)事務(wù)已經(jīng)存在,則先將這個(gè)存在的事務(wù)掛起)。如果使用JTATransactionManager的話(huà),則需要訪(fǎng)問(wèn)TransactionManager。

5、NOT_SUPPORTED

NOT_SUPPORTED表示該方法不應(yīng)該運(yùn)行在事務(wù)中,如果存在當(dāng)前事務(wù),在該方法運(yùn)行期間,當(dāng)前事務(wù)將被掛起。如果使用JTATransactionManager的話(huà),則需要訪(fǎng)問(wèn)TransactionManager。

6、NEVER

NEVER表示當(dāng)前方法不應(yīng)該運(yùn)行在事務(wù)上下文中,如果當(dāng)前正有一個(gè)事務(wù)在運(yùn)行,則會(huì)拋出異常。

7、NESTED

NESTED表示如果當(dāng)前已經(jīng)存在一個(gè)事務(wù),那么該方法將會(huì)在嵌套事務(wù)中運(yùn)行。嵌套的事務(wù)可以獨(dú)立于當(dāng)前事務(wù)進(jìn)行單獨(dú)地提交或回滾。如果當(dāng)前事務(wù)不存在,那么其行為與REQUIRED一樣。嵌套事務(wù)一個(gè)非常重要的概念就是內(nèi)層事務(wù)依賴(lài)于外層事務(wù)。外層事務(wù)失敗時(shí),會(huì)回滾內(nèi)層事務(wù)所做的動(dòng)作。而內(nèi)層事務(wù)操作失敗并不會(huì)引起外層事務(wù)的回滾。

綜上所述,NESTED和REQUIRES_NEW非常相似,都是開(kāi)啟一個(gè)屬于它自己的新事務(wù)。使用REQUIRES_NEW時(shí),內(nèi)層事務(wù)與外層事務(wù)就像兩個(gè)獨(dú)立的事務(wù)一樣,一旦內(nèi)層事務(wù)進(jìn)行了提交后,外層事務(wù)不能對(duì)其進(jìn)行回滾。當(dāng)內(nèi)部事務(wù)開(kāi)始執(zhí)行時(shí), 外部事務(wù)將被掛起, 內(nèi)務(wù)事務(wù)結(jié)束時(shí), 外部事務(wù)將繼續(xù)執(zhí)行。兩個(gè)事務(wù)互不影響,兩個(gè)事務(wù)不是一個(gè)真正的嵌套事務(wù),同時(shí)它還需要JTA事務(wù)管理器的支持。

使用NESTED時(shí),外層事務(wù)的回滾可以引起內(nèi)層事務(wù)的回滾。而內(nèi)層事務(wù)的異常并不會(huì)導(dǎo)致外層事務(wù)的回滾,它是一個(gè)真正的嵌套事務(wù)。嵌套事務(wù)開(kāi)始執(zhí)行時(shí), 它將取得一個(gè) savepoint,如果這個(gè)嵌套事務(wù)失敗, 將回滾到此savepoint。潛套事務(wù)是外部事務(wù)的一部分, 只有外部事務(wù)結(jié)束后它才會(huì)被提交。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Spring聲明式事務(wù)@Transactional知識(shí)點(diǎn)有哪些”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI