欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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() {
    }

注意這里注釋說(shuō)明了異常不會(huì)被捕獲,而且建議不在這里拋出TransactionException的子類;另外對(duì)于afterCommit有數(shù)據(jù)庫(kù)相關(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(),注意這里沒(méi)有try catch,說(shuō)明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ù)庫(kù)相關(guān)操作的建議使用PROPAGATION_REQUIRES_NEW這個(gè)事務(wù)傳播級(jí)別,不然afterCommit的db操作可能不會(huì)生效。

在事務(wù)提交之后做一些事情可能不需要TransactionSynchronizationManager.registerSynchronization這種方式也能實(shí)現(xiàn),也就是需要額外一層來(lái)調(diào)用事務(wù)操作,有異常會(huì)拋出,沒(méi)有異常則執(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)文章

  • Java Web學(xué)習(xí)教程之Hibernate And MyBatis的理解

    Java Web學(xué)習(xí)教程之Hibernate And MyBatis的理解

    這篇文章主要給大家介紹了關(guān)于Java Web學(xué)習(xí)教程之Hibernate And MyBatis的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • 解析ConcurrentHashMap: 紅黑樹(shù)的代理類(TreeBin)

    解析ConcurrentHashMap: 紅黑樹(shù)的代理類(TreeBin)

    ConcurrentHashMap是由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成。Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu),今天給大家普及java面試常見(jiàn)問(wèn)題---ConcurrentHashMap知識(shí),一起看看吧
    2021-06-06
  • java定時(shí)任務(wù)的實(shí)現(xiàn)方式

    java定時(shí)任務(wù)的實(shí)現(xiàn)方式

    這篇文章主要介紹了java定時(shí)任務(wù)的實(shí)現(xiàn)方式,在應(yīng)用里經(jīng)常都有用到在后臺(tái)跑定時(shí)任務(wù)的需求,如何進(jìn)行java定時(shí)任務(wù),本文為大家進(jìn)行講解,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 使用SpringBoot獲取resources文件路徑

    使用SpringBoot獲取resources文件路徑

    這篇文章主要介紹了使用SpringBoot獲取resources文件路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • SpringBoot利用validation實(shí)現(xiàn)優(yōu)雅的校驗(yàn)參數(shù)

    SpringBoot利用validation實(shí)現(xiàn)優(yōu)雅的校驗(yàn)參數(shù)

    數(shù)據(jù)的校驗(yàn)是交互式網(wǎng)站一個(gè)不可或缺的功能,如果數(shù)據(jù)庫(kù)中出現(xiàn)一個(gè)非法的郵箱格式,會(huì)讓運(yùn)維人員頭疼不已。本文將介紹如何利用validation來(lái)對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),感興趣的可以跟隨小編一起學(xué)習(xí)一下
    2022-06-06
  • Java和Android崩潰捕獲機(jī)制

    Java和Android崩潰捕獲機(jī)制

    這篇文章主要為大家介紹了Java和Android崩潰捕獲機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 初識(shí)Java設(shè)計(jì)模式適配器模式

    初識(shí)Java設(shè)計(jì)模式適配器模式

    這篇文章主要為大家詳細(xì)介紹了Java設(shè)計(jì)模式適配器模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解Idea 2019.2 安裝lombok插件失效問(wèn)題解決

    詳解Idea 2019.2 安裝lombok插件失效問(wèn)題解決

    這篇文章主要介紹了詳解Idea 2019.2 安裝lombok插件失效問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Java如何使用while循環(huán)計(jì)算一個(gè)整數(shù)的位數(shù)

    Java如何使用while循環(huán)計(jì)算一個(gè)整數(shù)的位數(shù)

    這篇文章主要介紹了Java使用while循環(huán)計(jì)算一個(gè)整數(shù)的位數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 淺談Java多線程編程中Boolean常量的同步問(wèn)題

    淺談Java多線程編程中Boolean常量的同步問(wèn)題

    這篇文章主要介紹了淺談Java多線程編程中Boolean常量的同步問(wèn)題,主要針對(duì)線程之間同步了不同的布爾對(duì)象的問(wèn)題,需要的朋友可以參考下
    2015-10-10

最新評(píng)論