偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Spring/SpringBoot中的聲明式事務(wù)和編程式事務(wù)源碼、區(qū)別、優(yōu)缺點(diǎn)、適用場(chǎng)景、實(shí)戰(zhàn)

開(kāi)發(fā) 架構(gòu)
本文介紹了SpringBoot框架中的聲明式事務(wù)和編程式事務(wù),并分析了它們的源碼實(shí)現(xiàn)、區(qū)別、優(yōu)缺點(diǎn)、適用場(chǎng)景以及實(shí)戰(zhàn)。無(wú)論是采用哪種方式來(lái)管理事務(wù),都需要考慮到業(yè)務(wù)需求和開(kāi)發(fā)團(tuán)隊(duì)的實(shí)際情況,選擇合適的事務(wù)處理方式,以確保系統(tǒng)的可靠性和穩(wěn)定性。

一、前言

在現(xiàn)代軟件開(kāi)發(fā)中,事務(wù)處理是必不可少的一部分。當(dāng)多個(gè)操作需要作為一個(gè)整體來(lái)執(zhí)行時(shí),事務(wù)可以確保數(shù)據(jù)的完整性和一致性,并避免出現(xiàn)異常和錯(cuò)誤情況。在SpringBoot框架中,我們可以使用聲明式事務(wù)和編程式事務(wù)來(lái)管理事務(wù)處理。其中事務(wù)的坑也是不少,比較常見(jiàn)的就是事務(wù)失效,大家可以看看!后面小編在出一篇事務(wù)失效場(chǎng)景哈,喜歡的可以關(guān)注,等待更新哈!

這篇博客將重點(diǎn)探討這兩種事務(wù)處理方式的源碼實(shí)現(xiàn)、區(qū)別、優(yōu)缺點(diǎn)、適用場(chǎng)景以及實(shí)戰(zhàn)。我們來(lái)接著說(shuō)事務(wù),里面還涉及到三個(gè)知識(shí)點(diǎn),大家可以自行百度好好了解!

  • 事務(wù)的特性
  • 事務(wù)的傳播行為
  • 隔離級(jí)別

本篇文章主要講的就是實(shí)現(xiàn)事務(wù)的兩種方式的分析!

讓我們開(kāi)始探索聲明式事務(wù)和編程式事務(wù)吧!

文章很長(zhǎng),耐心看完希望對(duì)你有幫助!

本文源碼是使用:springboot2.7.1。

二、開(kāi)啟使用和大致源碼實(shí)現(xiàn)

1、開(kāi)啟使用

我們?cè)趩?dòng)類上添加注解:@EnableTransactionManagement。

后續(xù)使用就可以添加注解@Transactional(rollbackFor = Exception.class)使用,或者是使用編程式事務(wù)使用了 !
后面我們?cè)谠敿?xì)演示怎么使用哈!

2、聲明式事務(wù)源碼

public class TransactionInterceptor extends TransactionAspectSupport 
    implements MethodInterceptor, Serializable{}

TransactionInterceptor UML圖:

圖片

聲明式事務(wù)主要是通過(guò)AOP實(shí)現(xiàn),主要包括以下幾個(gè)節(jié)點(diǎn):

  1. 啟動(dòng)時(shí)掃描@Transactional注解:在啟動(dòng)時(shí),Spring Boot會(huì)掃描所有使用了@Transactional注解的方法,并將其封裝成TransactionAnnotationParser對(duì)象。
  2. AOP 來(lái)實(shí)現(xiàn)事務(wù)管理的核心類依然是 TransactionInterceptor。TransactionInterceptor 是一個(gè)攔截器,用于攔截使用了 @Transactional 注解的方法
  3. 將TransactionInterceptor織入到目標(biāo)方法中:在AOP編程中,使用AspectJ編寫(xiě)切面類,通過(guò)@Around注解將TransactionInterceptor織入到目標(biāo)方法中。
  4. 在目標(biāo)方法執(zhí)行前創(chuàng)建事務(wù):在目標(biāo)方法執(zhí)行前,TransactionInterceptor會(huì)調(diào)用PlatformTransactionManager創(chuàng)建一個(gè)新的事務(wù),并將其納入到當(dāng)前線程的事務(wù)上下文中。
  5. 執(zhí)行目標(biāo)方法:在目標(biāo)方法執(zhí)行時(shí),如果發(fā)生異常,則將事務(wù)狀態(tài)標(biāo)記為ROLLBACK_ONLY;否則,將事務(wù)狀態(tài)標(biāo)記為COMMIT。
  6. 提交或回滾事務(wù):在目標(biāo)方法執(zhí)行完成后,TransactionInterceptor會(huì)根據(jù)事務(wù)狀態(tài)(COMMIT或ROLLBACK_ONLY)來(lái)決定是否提交或回滾事務(wù)。

源碼:

@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
        @Override
        @Nullable
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
        @Override
        public Object getTarget() {
            return invocation.getThis();
        }
        @Override
        public Object[] getArguments() {
            return invocation.getArguments();
        }
    });
}

下面是核心處理方法,把不太重要的代碼忽略了,留下每一步的節(jié)點(diǎn)。

@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
    final InvocationCallback invocation) throws Throwable {
    // 獲取事務(wù)屬性
    final TransactionManager tm = determineTransactionManager(txAttr);
    // 準(zhǔn)備事務(wù)
    TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
    // 執(zhí)行目標(biāo)方法
    Object retVal = invocation.proceedWithInvocation();
     // 回滾事務(wù)
    completeTransactionAfterThrowing(txInfo, ex);
    // 提交事務(wù)
    commitTransactionAfterReturning(txInfo);
}

3、編程式事務(wù)源碼

編程式事務(wù)主要下面的代碼:

public class TransactionTemplate extends DefaultTransactionDefinition
    implements TransactionOperations, InitializingBean{}

TransactionTemplate UML圖:

圖片

TransactionTemplate類的execute()方法封裝了事務(wù)的具體實(shí)現(xiàn),通過(guò)調(diào)用TransactionCallback對(duì)象的doInTransaction()方法來(lái)執(zhí)行業(yè)務(wù)邏輯并管理事務(wù)。在具體實(shí)現(xiàn)中,TransactionTemplate類會(huì)自動(dòng)控制事務(wù)的提交和回滾,并將異常拋出給上層調(diào)用者進(jìn)行處理。

@Override
@Nullable
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
    Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");

    if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
        return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
    }
    else {
        TransactionStatus status = this.transactionManager.getTransaction(this);
        T result;
        try {
            result = action.doInTransaction(status);
        }
        catch (RuntimeException | Error ex) {
            // Transactional code threw application exception -> rollback
            rollbackOnException(status, ex);
            throw ex;
        }
        catch (Throwable ex) {
            // Transactional code threw unexpected exception -> rollback
            rollbackOnException(status, ex);
            throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
        }
        this.transactionManager.commit(status);
        return result;
    }
}

三、兩者區(qū)別

上面說(shuō)了源碼里的大體實(shí)現(xiàn),下面我們來(lái)介紹一下兩者區(qū)別:

  1. 技術(shù)實(shí)現(xiàn)方式:聲明式事務(wù)是通過(guò)AOP技術(shù)來(lái)實(shí)現(xiàn)的,而編程式事務(wù)是通過(guò)編寫(xiě)具體的代碼來(lái)實(shí)現(xiàn)的。
  2. 代碼耦合度:聲明式事務(wù)可以將事務(wù)處理邏輯從業(yè)務(wù)代碼中分離出來(lái),從而降低代碼的耦合度。而編程式事務(wù)需要在業(yè)務(wù)代碼中顯式地調(diào)用事務(wù)管理代碼,因此會(huì)增加代碼的耦合度。
  3. 難易程度:聲明式事務(wù)相對(duì)來(lái)說(shuō)比較容易上手,開(kāi)發(fā)人員只需要學(xué)習(xí)注解或XML配置即可。而編程式事務(wù)需要開(kāi)發(fā)人員理解事務(wù)管理的底層機(jī)制,并編寫(xiě)具體的代碼。
  4. 性能影響:由于聲明式事務(wù)是由容器來(lái)處理的,所以在一些場(chǎng)景下可能會(huì)對(duì)性能產(chǎn)生影響,大事務(wù)會(huì)有很多問(wèn)題(下面在說(shuō)一下大事務(wù)出現(xiàn)的問(wèn)題)。而編程式事務(wù)由于直接調(diào)用事務(wù)管理API,相對(duì)來(lái)說(shuō)會(huì)有更好的性能表現(xiàn)。

總體而言,聲明式事務(wù)和編程式事務(wù)都有各自的優(yōu)缺點(diǎn),開(kāi)發(fā)人員需要根據(jù)具體需求選擇適合的方式來(lái)控制事務(wù)。

補(bǔ)充:

大事務(wù)時(shí)間過(guò)長(zhǎng)可能會(huì)導(dǎo)致以下問(wèn)題:

數(shù)據(jù)庫(kù)鎖定:當(dāng)事務(wù)涉及到大量的數(shù)據(jù)操作時(shí),事務(wù)可能會(huì)占用數(shù)據(jù)庫(kù)資源并長(zhǎng)時(shí)間鎖定相關(guān)數(shù)據(jù)。這可能會(huì)導(dǎo)致其他事務(wù)無(wú)法訪問(wèn)或修改這些數(shù)據(jù),從而降低系統(tǒng)的并發(fā)性能和吞吐量。

資源耗盡:長(zhǎng)時(shí)間運(yùn)行的事務(wù)需要占用更多的系統(tǒng)資源,如內(nèi)存和CPU等。如果系統(tǒng)資源不足,可能會(huì)導(dǎo)致系統(tǒng)出現(xiàn)延遲、死鎖等問(wèn)題,甚至導(dǎo)致系統(tǒng)崩潰。

事務(wù)失敗概率增加:當(dāng)事務(wù)時(shí)間過(guò)長(zhǎng)時(shí),事務(wù)執(zhí)行期間可能會(huì)發(fā)生各種錯(cuò)誤,如網(wǎng)絡(luò)故障、硬件故障、操作系統(tǒng)問(wèn)題等。此時(shí),事務(wù)可能無(wú)法成功提交,導(dǎo)致數(shù)據(jù)丟失或數(shù)據(jù)不一致。

應(yīng)用程序超時(shí):應(yīng)用程序通常會(huì)為每個(gè)事務(wù)設(shè)置一個(gè)超時(shí)時(shí)間,以避免事務(wù)持續(xù)時(shí)間過(guò)長(zhǎng)。如果事務(wù)持續(xù)時(shí)間超過(guò)設(shè)定的超時(shí)時(shí)間,則應(yīng)用程序可能會(huì)因?yàn)榈却聞?wù)完成而阻塞,最終導(dǎo)致應(yīng)用程序崩潰或超時(shí)。

回滾時(shí)間增加:如果事務(wù)失敗需要回滾,長(zhǎng)時(shí)間運(yùn)行的事務(wù)將需要更長(zhǎng)的時(shí)間來(lái)進(jìn)行回滾操作。這可能會(huì)導(dǎo)致數(shù)據(jù)不一致或丟失,并增加數(shù)據(jù)庫(kù)維護(hù)的工作量。因此,開(kāi)發(fā)人員應(yīng)該盡量避免事務(wù)時(shí)間過(guò)長(zhǎng),合理地設(shè)置事務(wù)范圍、優(yōu)化事務(wù)操作方式以及減少數(shù)據(jù)訪問(wèn)次數(shù)等措施,以提高系統(tǒng)的并發(fā)性能和吞吐量。

方案:

大事務(wù)可以拆分小的事務(wù),一下查詢方面的可以提取出來(lái),操作數(shù)據(jù)庫(kù)的抽離出來(lái)專門加上事務(wù)。也可以使用CompletableFuture組合式異步編排來(lái)解決大事務(wù)的問(wèn)題!

四、優(yōu)缺點(diǎn)

1、聲明式事務(wù)

聲明式事務(wù)通常通過(guò)AOP技術(shù)實(shí)現(xiàn),在方法或類級(jí)別上聲明事務(wù)屬性。聲明式事務(wù)的優(yōu)點(diǎn)包括:

簡(jiǎn)化代碼:開(kāi)發(fā)人員只需要關(guān)注業(yè)務(wù)邏輯,而無(wú)需手動(dòng)管理事務(wù),可以減少代碼復(fù)雜度和工作量。

可配置性強(qiáng):事務(wù)屬性可以通過(guò)XML文件、注解等方式進(jìn)行配置,靈活方便。
易于擴(kuò)展:可以通過(guò)AOP技術(shù)輕松地?cái)U(kuò)展使其支持新的事務(wù)策略。

聲明式事務(wù)存在以下缺點(diǎn):

限制較大:事務(wù)屬性需要在方法或類級(jí)別進(jìn)行聲明,這可能會(huì)導(dǎo)致某些情況下難以滿足特定的業(yè)務(wù)需求。

難以調(diào)試:由于事務(wù)是在AOP層面進(jìn)行管理的,因此在調(diào)試時(shí)可能難以追蹤事務(wù)管理的具體細(xì)節(jié)。

2、編程式事務(wù)

編程式事務(wù)通常通過(guò)API接口實(shí)現(xiàn),開(kāi)發(fā)人員可以在代碼中顯式地管理事務(wù)。

編程式事務(wù)的優(yōu)點(diǎn)包括:

靈活性強(qiáng):開(kāi)發(fā)人員可以在代碼中根據(jù)具體業(yè)務(wù)需要來(lái)控制事務(wù)的具體范圍和屬性。
易于調(diào)試:由于事務(wù)管理在代碼層面上實(shí)現(xiàn),因此開(kāi)發(fā)人員可以很容易地追蹤事務(wù)管理的細(xì)節(jié)。

編程式事務(wù)存在以下缺點(diǎn):

代碼復(fù)雜度高:需要在代碼中手動(dòng)處理事務(wù),并處理各種異常情況,可能會(huì)增加代碼的復(fù)雜度和工作量。
可配置性差:事務(wù)的范圍和屬性需要在代碼中顯式聲明,這可能會(huì)導(dǎo)致一些特定的業(yè)務(wù)需求難以滿足。

總之,聲明式事務(wù)和編程式事務(wù)各有優(yōu)缺點(diǎn)。開(kāi)發(fā)人員需要根據(jù)具體業(yè)務(wù)需求和場(chǎng)景選擇使用合適的事務(wù)管理方式。

五、使用場(chǎng)景

聲明式事務(wù)通常適用于以下場(chǎng)景:

  • 大型企業(yè)級(jí)應(yīng)用程序,需要管理多個(gè)事務(wù)。
  • 代碼結(jié)構(gòu)比較復(fù)雜,使用聲明式事務(wù)可以更好地管理和維護(hù)代碼(大事務(wù)參考上方的方案)。
  • 聲明式事務(wù)可以將事務(wù)管理與業(yè)務(wù)邏輯分離,從而使得應(yīng)用程序更加松耦合。

而編程式事務(wù)通常適用于以下場(chǎng)景:

  • 需要更精確地控制事務(wù)的范圍和處理邏輯。
  • 編程式事務(wù)通常比聲明式事務(wù)更加靈活,可以根據(jù)業(yè)務(wù)邏輯的需要來(lái)自定義事務(wù)的范圍、隔離級(jí)別以及回滾機(jī)制等。
  • 在某些高并發(fā)場(chǎng)景下,可以使用編程式事務(wù)僅針對(duì)需要操作的數(shù)據(jù)進(jìn)行鎖定,而不是對(duì)整個(gè)業(yè)務(wù)邏輯加事務(wù)。

在實(shí)際場(chǎng)景中,可以根據(jù)需求綜合考慮使用聲明式事務(wù)和編程式事務(wù)的優(yōu)勢(shì)來(lái)進(jìn)行選擇。

根據(jù)不同的用戶量來(lái)具體選擇,在幾乎沒(méi)有并發(fā)量的系統(tǒng)設(shè)計(jì)一條異步編排反而大材小用,可能造成資源的浪費(fèi);但是有需要等待遠(yuǎn)程API的響應(yīng)時(shí),使用異步編排可以將等待時(shí)間最小化,并使得應(yīng)用程序不必阻塞等待API響應(yīng),從而提高用戶體驗(yàn)。

很多事情沒(méi)有絕對(duì)化,只有相對(duì)化,只要能支持現(xiàn)有正常的使用,不管什么樣的設(shè)計(jì)都是沒(méi)問(wèn)題的! 可能好的設(shè)計(jì)會(huì)使系統(tǒng)在經(jīng)受并發(fā)量增大的過(guò)程中無(wú)感,還是要調(diào)研清楚,從而設(shè)計(jì)出更好的方案,防止資源浪費(fèi)!

盡管小編還沒(méi)有什么架構(gòu)經(jīng)驗(yàn),但還是對(duì)架構(gòu)充滿興趣,不想做架構(gòu)師的開(kāi)發(fā)不是好開(kāi)發(fā)哈!!當(dāng)然你也可以走管理?。?/p>

六、實(shí)戰(zhàn)

1、聲明式事務(wù)

這里就簡(jiǎn)單模擬一下,為了模擬報(bào)錯(cuò),把OperIp設(shè)置為唯一!

@Transactional(rollbackFor = Exception.class)大家經(jīng)常使用,就不多演示了!

@Transactional(rollbackFor = Exception.class)
@Override
public void template() {
    SysLog sysLog = new SysLog();
    sysLog.setOperIp("123");
    SysLog sysLog1 = new SysLog();
    sysLog1.setOperIp("hhh");
    log.info("插入第一條數(shù)據(jù)開(kāi)始========");
    testMapper.insert(sysLog);
    log.info("插入第一條數(shù)據(jù)完成========");
    log.info("插入第二條數(shù)據(jù)開(kāi)始========");
    testMapper.insert(sysLog);
    log.info("插入第二條數(shù)據(jù)完成========");

}

此時(shí)數(shù)據(jù)沒(méi)有數(shù)據(jù),全部回滾成功!

圖片

2、編程式事務(wù)

首先注入TransactionTemplate:

@Autowired
private TransactionTemplate transactionTemplate;

后面直接使用即可:

@Override
public void template() {
    SysLog sysLog = new SysLog();
    sysLog.setOperIp("123");
    SysLog sysLog1 = new SysLog();
    sysLog1.setOperIp("hhh");
    log.info("插入第一條數(shù)據(jù)開(kāi)始========");
    testMapper.insert(sysLog);
    log.info("插入第一條數(shù)據(jù)完成========");

    transactionTemplate.execute(status -> {
        log.info("編程式事務(wù)中:插入第一條數(shù)據(jù)開(kāi)始========");
        testMapper.insert(sysLog1);
        log.info("編程式事務(wù)中:插入第一條數(shù)據(jù)完成========");
        log.info("編程式事務(wù)中:插入第二條數(shù)據(jù)開(kāi)始========");
        int insert = testMapper.insert(sysLog);
        log.info("編程式事務(wù)中:插入第二條數(shù)據(jù)完成========");
        return insert;
    });
}

圖片

查看數(shù)據(jù)庫(kù),第一條不在編程式事務(wù)內(nèi)不會(huì)參與回滾!

圖片

七、總結(jié)

本文介紹了SpringBoot框架中的聲明式事務(wù)和編程式事務(wù),并分析了它們的源碼實(shí)現(xiàn)、區(qū)別、優(yōu)缺點(diǎn)、適用場(chǎng)景以及實(shí)戰(zhàn)。
無(wú)論是采用哪種方式來(lái)管理事務(wù),都需要考慮到業(yè)務(wù)需求和開(kāi)發(fā)團(tuán)隊(duì)的實(shí)際情況,選擇合適的事務(wù)處理方式,以確保系統(tǒng)的可靠性和穩(wěn)定性。

希望通過(guò)本文的介紹,你能夠更好地理解聲明式事務(wù)和編程式事務(wù)的概念和原理,在開(kāi)發(fā)過(guò)程中選擇合適的事務(wù)處理方式,提高項(xiàng)目的可維護(hù)性和穩(wěn)定性。

責(zé)任編輯:姜華 來(lái)源: 小王博客基地
相關(guān)推薦

2024-11-13 19:03:14

2009-06-22 09:01:57

Spring聲明式事務(wù)

2009-02-11 13:08:29

事務(wù)提交事務(wù)管理Spring

2021-03-04 09:00:00

架構(gòu)Lambda工具

2009-02-11 11:14:31

事務(wù)管理事務(wù)開(kāi)始Spring

2021-07-13 07:31:26

Springboot編程事務(wù)管理

2021-09-06 13:42:14

Spring聲明式事務(wù)

2009-06-22 11:01:12

2023-02-22 09:16:22

2023-03-20 09:17:13

策略模式Springboot

2024-01-25 10:14:09

HashSetHashMapJava

2021-03-08 08:48:02

應(yīng)用場(chǎng)景項(xiàng)目

2009-06-17 14:57:11

Spring事務(wù)管理

2009-06-08 17:56:00

SpringJDBC事務(wù)

2024-01-29 08:28:01

Spring事務(wù)失效

2021-04-15 08:01:27

Spring聲明式事務(wù)

2024-06-13 08:04:23

2022-02-14 16:53:57

Spring項(xiàng)目數(shù)據(jù)庫(kù)

2019-07-25 15:32:35

分布式事務(wù)微服務(wù)系統(tǒng)架構(gòu)

2023-02-02 09:37:59

消息隊(duì)列MQ
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)