1.Spring對(duì)事物的支持一般有兩種方式
-
編程式事務(wù)管理:通過(guò)?
TransactionTemplate
或者TransactionManager
手動(dòng)管理事務(wù),實(shí)際應(yīng)用中很少使用,這不是本文的重點(diǎn),就不在這里贅述。 - 聲明式事務(wù)管理:使用場(chǎng)景最多,也是最推薦使用的方式,直接加上@Transactional注解即可。
2.Transactional注解幾大參數(shù)解釋
@Transactional 注解是用于聲明事務(wù)性方法的注解,通常用于標(biāo)記在服務(wù)層的方法上。該注解提供了一些參數(shù),用于配置事務(wù)的一些屬性。以下是幾個(gè)常用的參數(shù)及其解釋?zhuān)?/p>
- propagation(傳播行為):
- - 用于指定事務(wù)的傳播行為。包括諸如 `REQUIRED`、`REQUIRES_NEW`、`SUPPORTS`、`NOT_SUPPORTED` 等。該參數(shù)定義了方法被嵌套調(diào)用時(shí),事務(wù)如何傳播。
- 2. isolation(隔離級(jí)別):
- - 用于指定事務(wù)的隔離級(jí)別。包括 `DEFAULT`、`READ_UNCOMMITTED`、`READ_COMMITTED`、`REPEATABLE_READ`、`SERIALIZABLE`。該參數(shù)定義了事務(wù)處理過(guò)程中對(duì)數(shù)據(jù)的隔離程度。
- 3. readOnly(只讀):
- - 用于指定事務(wù)是否是只讀的。如果設(shè)置為 `true`,表示只讀取數(shù)據(jù)而不修改,可以優(yōu)化事務(wù)處理。默認(rèn)值為 `false`。
- 4. timeout`(超時(shí)時(shí)間):
- - 用于指定事務(wù)的超時(shí)時(shí)間,單位為秒。如果事務(wù)執(zhí)行時(shí)間超過(guò)指定的時(shí)間,則會(huì)被強(qiáng)制回滾。默認(rèn)值為 `-1`,表示沒(méi)有超時(shí)限制。
- 5. rollbackFor` 和 noRollbackFor:
- - 用于指定在哪些異常情況下回滾事務(wù)。`rollbackFor` 指定哪些異常時(shí)回滾,`noRollbackFor` 指定哪些異常時(shí)不回滾??梢詡魅氘惓n?lèi)型的數(shù)組
?重點(diǎn)講解propagation(傳播行為)
七大參數(shù)設(shè)置:?
?場(chǎng)景:
假設(shè)有這樣的場(chǎng)景 有A類(lèi)和B類(lèi) A類(lèi)內(nèi)部有一個(gè)事務(wù)方法 B類(lèi)有一個(gè)事務(wù)方法
class A{ public B b; @Transactional public void a(){ //1.對(duì)數(shù)據(jù)表A進(jìn)行插入操作方法 System.out.println("往A插入數(shù)據(jù)"); //2.對(duì)數(shù)據(jù)表B進(jìn)行插入操作方法 b.b(); // System.out.println("往A繼續(xù)插入數(shù)據(jù)"); } } class B{ @Transactional public void b(){ //對(duì)數(shù)據(jù)庫(kù)進(jìn)行插入操作方法 System.out.println("更新表單 插入數(shù)據(jù)"); } }
這種是一種常見(jiàn)的嵌套事務(wù) 如果都存在事務(wù)可能它的SQL是這樣的
BEGIN UPDATE A; -- B類(lèi)的事務(wù)來(lái)了 BEGIN UPDATE B; COMMIT; -- UPDATE A; COMMIT;
這種寫(xiě)法在MYSQL是不支持的,如果執(zhí)行了B事務(wù)那么A的部門(mén)事務(wù)失效。如果想要實(shí)現(xiàn)這兩個(gè)事務(wù)都存在怎么辦?那我們可以直接把B事務(wù)的BEGIN和COMMIT去掉 讓B事務(wù)融入到A事務(wù)中即可。
BEGIN UPDATE A; -- B類(lèi)的事務(wù)來(lái)了 UPDATE B; -- UPDATE A; COMMIT;
這種情況其實(shí)就代表了傳播行為的?REQUIRED 傳播行為
具體來(lái)說(shuō),當(dāng)一個(gè)方法使用?@Transactional(propagation = Propagation.REQUIRED)
?進(jìn)行標(biāo)記時(shí),它的行為如下:
-
存在事務(wù)時(shí):?方法將在當(dāng)前事務(wù)中運(yùn)行,與調(diào)用該方法的外部事務(wù)合并為一個(gè)事務(wù)。
-
不存在事務(wù)時(shí):?方法將啟動(dòng)一個(gè)新的事務(wù)。
這種情況會(huì)出現(xiàn)一個(gè)問(wèn)題 就是外部的事務(wù)融入到當(dāng)前事務(wù)中的時(shí)候如果出錯(cuò)那么整個(gè)事務(wù)都會(huì)進(jìn)行回滾。
解決這種情況有一個(gè)名詞叫掛起 掛起解釋就是使用其他線程獲取不同的數(shù)據(jù)庫(kù)連接 如果執(zhí)行兩個(gè)不同的事務(wù) 這樣就不會(huì)影響原本事務(wù)的流程。
-- 線程1獲取到數(shù)據(jù)庫(kù)連接1 執(zhí)行A事務(wù)的流程 BEGIN UPDATE A; -- B類(lèi)的事務(wù)來(lái)了 線程2獲取到數(shù)據(jù)庫(kù)連接2 執(zhí)行B事務(wù)的流程 BEGIN UPDATE B; COMMIT; -- 執(zhí)行后 重新將線程B切換到線程A 來(lái)執(zhí)行后續(xù)流程 UPDATE A; COMMIT;
這種情況也是傳播行為中的REQUIRES_NEW?傳播行為
具體來(lái)說(shuō),當(dāng)一個(gè)方法使用?@Transactional(propagation = Propagation.REQUIRES_NEW)
?進(jìn)行標(biāo)記時(shí),它的行為如下:
-
存在事務(wù)時(shí):?方法將掛起當(dāng)前的事務(wù),并啟動(dòng)一個(gè)新的事務(wù)。在該方法執(zhí)行完畢后,新事務(wù)將被提交或回滾,然后恢復(fù)掛起的事務(wù)。
-
不存在事務(wù)時(shí):?方法將啟動(dòng)一個(gè)新的事務(wù)。
還有一種情況就是嵌套事務(wù),MySQL是不支持嵌套事務(wù)的,但Mybatis在這個(gè)層面加入了保存點(diǎn)和回滾點(diǎn)來(lái)支持。
BEGIN UPDATE a set score=100 where id=1; Savepoint a; update b set score=200 where id=2; ROLLBACK to a; -- 如果B事務(wù)出現(xiàn)問(wèn)題 不會(huì)影響后面的事務(wù) UPDATE a set score=300 where id=3; COMMIT;
當(dāng)一個(gè)方法使用?@Transactional(propagation = Propagation.NESTED)
?進(jìn)行標(biāo)記時(shí),它的行為如下:
-
存在事務(wù)時(shí):?方法將在一個(gè)嵌套事務(wù)中運(yùn)行。如果當(dāng)前存在事務(wù),則將創(chuàng)建一個(gè)新的保存點(diǎn),并在方法執(zhí)行時(shí)將該保存點(diǎn)設(shè)為當(dāng)前事務(wù)的回滾點(diǎn)。如果方法執(zhí)行后,嵌套事務(wù)回滾,則只會(huì)回滾到該保存點(diǎn),而不會(huì)影響外部事務(wù)。
-
不存在事務(wù)時(shí):?方法將啟動(dòng)一個(gè)新的事務(wù),行為與?
REQUIRED
?類(lèi)似。
上面三種情況其實(shí)就能解決掉百分之99%的事務(wù)嵌套問(wèn)題,Spring為我們提供了七個(gè)事務(wù)傳播行為,解釋后四個(gè)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-794665.html
- SUPPORTS:支持當(dāng)前事務(wù),B事務(wù)設(shè)置了這個(gè)傳播行為,如果A有事務(wù)就融入到A事務(wù)中,如果沒(méi)有就不開(kāi)啟事務(wù),這個(gè)使用場(chǎng)景適用于只讀和只有多SELECT場(chǎng)景下。
- ?MANDATORY:只支持當(dāng)前事務(wù),B事務(wù)如果設(shè)置了這個(gè)傳播行為,那么它必須要被傳入到一個(gè)有事務(wù)的方法中,不然就會(huì)拋出異常。
- NOT_SUPPORTED:不支持事務(wù),如果B事務(wù)設(shè)置了這個(gè)傳播行為,那么它如果被傳入到A事務(wù)方法內(nèi),那么它會(huì)將A事務(wù)進(jìn)行掛起已非事務(wù)的方法來(lái)運(yùn)行。
- NEVER:不支持事務(wù),只要有事務(wù)運(yùn)行,就直接拋出異常。
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-794665.html
到了這里,關(guān)于Spring事務(wù)傳播機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!