最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring的TransactionSynchronizationAdapter事務(wù)源碼解析

 更新時(shí)間:2023年09月11日 11:31:52   作者:codecraft  
這篇文章主要介紹了spring的TransactionSynchronizationAdapter事務(wù)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下spring的TransactionSynchronizationAdapter

示例代碼

public void insert(TechBook techBook){
        bookMapper.insert(techBook);
       // send after tx commit but is async
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                System.out.println("send email after transaction commit...");
            }
        }
       );
        System.out.println("service end");
    }
使用TransactionSynchronizationManager.registerSynchronization注冊(cè)了一個(gè)TransactionSynchronizationAdapter,在其afterCommit方法也就是事務(wù)提交成功之后執(zhí)行一些額外邏輯

TransactionSynchronizationAdapter

org/springframework/transaction/support/TransactionSynchronizationAdapter.java

public abstract class TransactionSynchronizationAdapter implements TransactionSynchronization, Ordered {
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
    @Override
    public void suspend() {
    }
    @Override
    public void resume() {
    }
    @Override
    public void flush() {
    }
    @Override
    public void beforeCommit(boolean readOnly) {
    }
    @Override
    public void beforeCompletion() {
    }
    @Override
    public void afterCommit() {
    }
    @Override
    public void afterCompletion(int status) {
    }
}
TransactionSynchronizationAdapter是個(gè)抽象類,聲明實(shí)現(xiàn)TransactionSynchronization及Ordered接口

TransactionSynchronization

org/springframework/transaction/support/TransactionSynchronization.java

/**
     * Invoked after transaction commit. Can perform further operations right
     * <i>after</i> the main transaction has <i>successfully</i> committed.
     * <p>Can e.g. commit further operations that are supposed to follow on a successful
     * commit of the main transaction, like confirmation messages or emails.
     * <p><b>NOTE:</b> The transaction will have been committed already, but the
     * transactional resources might still be active and accessible. As a consequence,
     * any data access code triggered at this point will still "participate" in the
     * original transaction, allowing to perform some cleanup (with no commit following
     * anymore!), unless it explicitly declares that it needs to run in a separate
     * transaction. Hence: <b>Use {@code PROPAGATION_REQUIRES_NEW} for any
     * transactional operation that is called from here.</b>
     * @throws RuntimeException in case of errors; will be <b>propagated to the caller</b>
     * (note: do not throw TransactionException subclasses here!)
     */
    default void afterCommit() {
    }

注意這里注釋說明了異常不會(huì)被捕獲,而且建議不在這里拋出TransactionException的子類;另外對(duì)于afterCommit有數(shù)據(jù)庫相關(guān)操作的建議使用PROPAGATION_REQUIRES_NEW這個(gè)事務(wù)傳播級(jí)別,不然afterCommit的操作可能不會(huì)生效

registerSynchronization

org/springframework/transaction/support/TransactionSynchronizationManager.java

private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
            new NamedThreadLocal<>("Transaction synchronizations");
    /**
     * Register a new transaction synchronization for the current thread.
     * Typically called by resource management code.
     * <p>Note that synchronizations can implement the
     * {@link org.springframework.core.Ordered} interface.
     * They will be executed in an order according to their order value (if any).
     * @param synchronization the synchronization object to register
     * @throws IllegalStateException if transaction synchronization is not active
     * @see org.springframework.core.Ordered
     */
    public static void registerSynchronization(TransactionSynchronization synchronization)
            throws IllegalStateException {
        Assert.notNull(synchronization, "TransactionSynchronization must not be null");
        Set<TransactionSynchronization> synchs = synchronizations.get();
        if (synchs == null) {
            throw new IllegalStateException("Transaction synchronization is not active");
        }
        synchs.add(synchronization);
    }
TransactionSynchronizationManager的registerSynchronization方法會(huì)把TransactionSynchronization注冊(cè)到當(dāng)前線程的synchronizations

processCommit

org/springframework/transaction/support/AbstractPlatformTransactionManager.java

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
        try {
            boolean beforeCompletionInvoked = false;
            try {
                boolean unexpectedRollback = false;
                prepareForCommit(status);
                triggerBeforeCommit(status);
                triggerBeforeCompletion(status);
                beforeCompletionInvoked = true;
                if (status.hasSavepoint()) {
                    if (status.isDebug()) {
                        logger.debug("Releasing transaction savepoint");
                    }
                    unexpectedRollback = status.isGlobalRollbackOnly();
                    status.releaseHeldSavepoint();
                }
                else if (status.isNewTransaction()) {
                    if (status.isDebug()) {
                        logger.debug("Initiating transaction commit");
                    }
                    unexpectedRollback = status.isGlobalRollbackOnly();
                    doCommit(status);
                }
                else if (isFailEarlyOnGlobalRollbackOnly()) {
                    unexpectedRollback = status.isGlobalRollbackOnly();
                }
                // Throw UnexpectedRollbackException if we have a global rollback-only
                // marker but still didn't get a corresponding exception from commit.
                if (unexpectedRollback) {
                    throw new UnexpectedRollbackException(
                            "Transaction silently rolled back because it has been marked as rollback-only");
                }
            }
            catch (UnexpectedRollbackException ex) {
                // can only be caused by doCommit
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
                throw ex;
            }
            catch (TransactionException ex) {
                // can only be caused by doCommit
                if (isRollbackOnCommitFailure()) {
                    doRollbackOnCommitException(status, ex);
                }
                else {
                    triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
                }
                throw ex;
            }
            catch (RuntimeException | Error ex) {
                if (!beforeCompletionInvoked) {
                    triggerBeforeCompletion(status);
                }
                doRollbackOnCommitException(status, ex);
                throw ex;
            }
            // Trigger afterCommit callbacks, with an exception thrown there
            // propagated to callers but the transaction still considered as committed.
            try {
                triggerAfterCommit(status);
            }
            finally {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
            }
        }
        finally {
            cleanupAfterCompletion(status);
        }
    }
    private void triggerAfterCommit(DefaultTransactionStatus status) {
        if (status.isNewSynchronization()) {
            if (status.isDebug()) {
                logger.trace("Triggering afterCommit synchronization");
            }
            TransactionSynchronizationUtils.triggerAfterCommit();
        }
    }
AbstractPlatformTransactionManager的processCommit方法,在提交成功之后觸發(fā)triggerAfterCommit,這里調(diào)用了TransactionSynchronizationUtils.triggerAfterCommit(),注意這里沒有try catch,說明triggerAfterCommit的異常最終會(huì)拋給調(diào)用方

triggerAfterCommit

org/springframework/transaction/support/TransactionSynchronizationUtils.java

public static void triggerAfterCommit() {
        invokeAfterCommit(TransactionSynchronizationManager.getSynchronizations());
    }
    public static void invokeAfterCommit(@Nullable List<TransactionSynchronization> synchronizations) {
        if (synchronizations != null) {
            for (TransactionSynchronization synchronization : synchronizations) {
                synchronization.afterCommit();
            }
        }
    }

 這里遍歷synchronizations執(zhí)行afterCommit方法,如果其中有一個(gè)有異常拋出則中斷

小結(jié)

使用TransactionSynchronizationManager.registerSynchronization可以在當(dāng)前線程的事務(wù)注冊(cè)一個(gè)TransactionSynchronizationAdapter,可以在afterCommit方法也就是事務(wù)提交成功之后執(zhí)行一些額外邏輯;注意這里拋出的異常不影響事務(wù)提交,但是異常不會(huì)被catch需要由調(diào)用方處理,對(duì)于afterCommit有數(shù)據(jù)庫相關(guān)操作的建議使用PROPAGATION_REQUIRES_NEW這個(gè)事務(wù)傳播級(jí)別,不然afterCommit的db操作可能不會(huì)生效。

在事務(wù)提交之后做一些事情可能不需要TransactionSynchronizationManager.registerSynchronization這種方式也能實(shí)現(xiàn),也就是需要額外一層來調(diào)用事務(wù)操作,有異常會(huì)拋出,沒有異常則執(zhí)行事務(wù)提交之后的事情,前提就是事務(wù)回滾異常不能被吞掉,不然外層調(diào)用可能以為事務(wù)成功了還有一種方式就是使用TransactionalEventListener,這種方式比TransactionSynchronizationManager.registerSynchronization更為優(yōu)雅一些

doc

以上就是spring的TransactionSynchronizationAdapter事務(wù)源碼解析的詳細(xì)內(nèi)容,更多關(guān)于spring TransactionSynchronizationAdapter的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MyBatis-Plus中的LambdaQuery用法實(shí)例詳解

    MyBatis-Plus中的LambdaQuery用法實(shí)例詳解

    LambdaQueryWrapper是MyBatis-Plus的類型安全查詢工具,通過Lambda表達(dá)式簡化條件構(gòu)建,避免硬編碼字段名,提升代碼可讀性、維護(hù)性及重構(gòu)友好性,適用于單表查詢場景,本文給大家介紹MyBatis-Plus中的LambdaQuery用法,感興趣的朋友一起看看吧
    2025-07-07
  • java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作

    java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作

    這篇文章主要介紹了java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • springboot?yml配置文件值注入方式

    springboot?yml配置文件值注入方式

    這篇文章主要介紹了springboot?yml配置文件值注入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java中map內(nèi)部存儲(chǔ)方式解析

    Java中map內(nèi)部存儲(chǔ)方式解析

    這篇文章主要介紹了Java中map內(nèi)部存儲(chǔ)方式解析的相關(guān)內(nèi)容,涉及其實(shí)現(xiàn)方式,以及對(duì)存儲(chǔ)方式作了簡單的比較,具有一定參考價(jià)值,需要的朋友可了解下。
    2017-10-10
  • Eclipse配置tomcat發(fā)布路徑的問題wtpwebapps解決辦法

    Eclipse配置tomcat發(fā)布路徑的問題wtpwebapps解決辦法

    這篇文章主要介紹了Eclipse配置tomcat發(fā)布路徑的問題wtpwebapps解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Milvus快速入門及用Java操作Milvus的全過程

    Milvus快速入門及用Java操作Milvus的全過程

    Milvus是面向向量的數(shù)據(jù)庫,通過相似性搜索處理非結(jié)構(gòu)化數(shù)據(jù)特征,本文給大家介紹Milvus快速入門以及用Java操作Milvus的方法,感興趣的朋友一起看看吧
    2025-09-09
  • Java 關(guān)于String字符串原理上的問題

    Java 關(guān)于String字符串原理上的問題

    字符串廣泛應(yīng)用 在 Java 編程中,在 Java 中字符串屬于對(duì)象,Java 提供了 String 類來創(chuàng)建和操作字符串,讓我們一起來了解它
    2022-04-04
  • 應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法

    應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法

    這篇文章主要介紹了應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法,通過一個(gè)自定義函數(shù)結(jié)合泛型與反射的應(yīng)用實(shí)現(xiàn)導(dǎo)出CSV文件的功能,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-12-12
  • Token安全存儲(chǔ)的幾種方式小結(jié)

    Token安全存儲(chǔ)的幾種方式小結(jié)

    在現(xiàn)代 Web 應(yīng)用中,身份認(rèn)證與授權(quán)是確保系統(tǒng)安全性的重要部分,Token被廣泛應(yīng)用,作為實(shí)現(xiàn)身份認(rèn)證的主要方式,然而,如何安全地存儲(chǔ)這些 Token,是每個(gè)開發(fā)者在構(gòu)建前端應(yīng)用時(shí)必須考慮的問題,本文將深入探討Token安全存儲(chǔ)的幾種方式,需要的朋友可以參考下
    2025-04-04
  • 詳解SpringBoot接收參數(shù)的五種形式

    詳解SpringBoot接收參數(shù)的五種形式

    在Spring Boot中,接收參數(shù)可以通過多種方式實(shí)現(xiàn),本文給大家介紹了SpringBoot接收參數(shù)的五種形式,并通過代碼和圖文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03

最新評(píng)論

鹤岗市| 昌图县| 隆德县| 永宁县| 富阳市| 东阿县| 兴安盟| 河西区| 泸溪县| 铁岭市| 阳谷县| 高碑店市| 黑山县| 吴旗县| 枞阳县| 南昌县| 临夏市| 九江市| 财经| 泰安市| 库伦旗| 丹东市| 松溪县| 龙川县| 大竹县| 原平市| 且末县| 穆棱市| 张家口市| 桃源县| 行唐县| 西贡区| 天柱县| 潢川县| 高青县| 二连浩特市| 长宁区| 富平县| 双峰县| 巨野县| 疏勒县|