TransactionManager事务提交之后执行xxx操作

需求:在保证事务提交之后执行某些操作。


image.png

解决:

TransactionSynchronizationManager.registerSynchronization(
    new TransactionSynchronizationAdapter() {    
        @Override    
        public void afterCommit() {        
          //do something   
        }
});

源码:

/**
     * 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);
    }

看第一行注释 Register a new transaction synchronization for the current thread.

为当前线程注册一个事务synchronization ,

注册到哪了呢,猜也猜到了,当然是ThreadLocal啦!

注册的是嘛玩意呢?

从最初的代码可以看到注册是的 TransactionSynchronizationAdapter(从明明后缀可以知道这个是适配器接口)

源码中ThreadLocal中维护的是一个 TransactionSynchronization的列表

TransactionSynchronization定义了beforeCommit,afterCommit等方法

TransactionSynchronizationAdapter正是TransactionSynchronization的抽象实现

image.png

可以看到都是空实现,这样设计的好处是,当业务需要用到时,无需实现接口全部的方法, 按需实现即可。典型的适配器模式。

讲了那么多,看一下事务提交后是怎么调用TransactionSynchronization 的呢??? 看到这里估计你心中已有了答案。

org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit

//提交事务的核心逻辑
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    //…… 省略无关代码
    //提交事务
    doCommit(status);
    //看这里,处理提交事务之后的逻辑
    triggerAfterCommit(status);
    //……省略无关代码
 
}


private void triggerAfterCommit(DefaultTransactionStatus status) {
    TransactionSynchronizationUtils.triggerAfterCommit();
}

//TransactionSynchronizationManager.getSynchronizations()就是获取所有注册的Synchronizations并排个序啥的
public static void triggerAfterCommit() {
    invokeAfterCommit(TransactionSynchronizationManager.getSynchronizations());
}


//最终就在这了
public static void invokeAfterCommit(@Nullable List<TransactionSynchronization> synchronizations) {
        if (synchronizations != null) {
            for (TransactionSynchronization synchronization : synchronizations) {
                synchronization.afterCommit();
            }
        }
}

总结: 一个好的框架里有非常多的设计思想和code风格值的学习。
当前还有一种更为优雅的方式(注解+事件驱动,摆脱硬编码,减少代码侵入),可以解决类似问题。
预知后事如何,且听下回分解

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。