需求:在保证事务提交之后执行某些操作。
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
的抽象实现
可以看到都是空实现,这样设计的好处是,当业务需要用到时,无需实现接口全部的方法, 按需实现即可。典型的适配器模式。
讲了那么多,看一下事务提交后是怎么调用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风格值的学习。
当前还有一种更为优雅的方式(注解+事件驱动
,摆脱硬编码,减少代码侵入),可以解决类似问题。
预知后事如何,且听下回分解
网友评论