写作原由:
工作中需要手工进行事务封装,故此不得不用到TransactionSynchronizationAdapter。故此看到项目中都是如下写法:
故此这边想进一步学习其原理和封装一个工具类:
概述:
TransactionSynchronizationAdapter
是 Spring 框架中的一个类,它实现了 TransactionSynchronization
接口,提供了一种方便的方式来使用事务同步回调。 通过实现 TransactionSynchronization
接口,开发者可以在事务的不同阶段(如提交前、提交后、回滚后等)执行自定义的逻辑。
原理:
TransactionSynchronizationManager
是 Spring 中管理事务同步的中心类。它维护了当前线程的事务同步回调,这些回调与当前线程绑定的资源(如数据库连接)相关联。
当一个事务被管理时,你可以通过 TransactionSynchronizationManager.registerSynchronization
方法注册一个 TransactionSynchronization
实例。Spring 会在事务的相应阶段调用该实例的回调方法。
TransactionSynchronizationAdapter
是 TransactionSynchronization
的一个空实现,它为所有的方法提供了空操作。你可以选择性地覆盖你感兴趣的方法,而不是实现接口中的所有方法。
优点:
- 灵活性:允许在事务的关键阶段插入自定义逻辑,如资源清理、统计信息更新、后续操作触发等。
- 便利性 :通过提供默认实现,
TransactionSynchronizationAdapter
使得你只需覆盖你关心的回调方法。 - 一致性:确保在事务的正确阶段执行操作,有助于保持代码的一致性和可维护性。
- 集成:与 Spring 的事务管理无缝集成,不需要额外的事务控制代码。
缺点:
- 依赖于Spring框架 :使用
TransactionSynchronizationAdapter
需要依赖于Spring框架,这对于非Spring项目来说可能是一个限制。 - 线程局限性 :
TransactionSynchronization
是与线程绑定的,这意味着它只能在事务控制的同一线程中工作。 - 性能考虑:如果在事务同步回调中执行耗时操作,可能会影响事务的性能。
- 复杂性:在复杂的事务场景中,管理多个同步回调可能会增加代码的复杂性。
使用场景:
- 在事务提交后发送消息或通知。
- 在事务完成后执行某些统计或日志记录。
- 在事务回滚后进行资源清理或状态重置。
- 在事务提交前进行最后的校验或准备工作。
如何使用:
要使用 TransactionSynchronizationAdapter
,你需要创建它的一个匿名类或子类,并覆盖你感兴趣的方法。然后,你可以在事务代码中注册这个同步适配器。下面是一个简单的例子,展示了如何在事务提交后执行一些自定义逻辑:
java
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @Author derek_smart
* @Date 2024/5/31 10:01
* @Description
* <p> 简单示例
*/
public class MyService {
public void performTransactionalOperation() {
// 执行一些事务操作...
// 注册事务同步适配器
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
// 事务提交后执行的逻辑
doAfterTransactionCommit();
}
}
);
}
private void doAfterTransactionCommit() {
// 自定义逻辑...
}
}
在这个例子中,afterCommit
方法被覆盖以实现特定的逻辑,这个逻辑将在事务成功提交后执行。你可以根据需要覆盖其他的方法。
请注意,为了使这个同步适配器工作,你的代码需要运行在 Spring 管理的事务环境中。如果你不在事务的上下文中使用 TransactionSynchronizationManager.registerSynchronization
方法,那么注册的同步适配器将不会被调用。
TransactionSynchronizationAdapter是 Spring 框架提供的一个便利类,它实现了
TransactionSynchronization 接口。
TransactionSynchronization 接口定义了一系列的回调方法,这些方法在事务的不同阶段被调用。
TransactionSynchronizationAdapter` 为这些方法提供了默认的空实现,你可以通过继承这个类并覆盖特定的方法来实现自己的逻辑。### 核心方法:
以下是 TransactionSynchronization
接口中一些核心的回调方法,这些方法在 TransactionSynchronizationAdapter
中都有默认实现:
beforeCommit(boolean readOnly)
: 事务提交之前调用,readOnly
标志指示事务是否是只读的。beforeCompletion()
: 事务完成之前(即提交或回滚之前)调用。afterCommit()
: 事务提交之后调用。afterCompletion(int status)
: 事务完成之后调用,status
表示完成状态(提交或回滚)。suspend()
: 事务挂起时调用。resume()
: 事务恢复时调用。flush()
: 清理挂起资源时调用。
流程图:
在流程图中,以下参与者:
- Client: 调用事务管理器来开始和结束事务的客户端代码。
- TransactionManager: 管理事务的边界,负责开始、提交或回滚事务。
- TransactionSynchronizationManager: 管理事务同步回调的注册和触发。
- TransactionSynchronizationAdapter: 提供默认实现,可以被覆盖以执行自定义逻辑。
- CustomLogic: 自定义逻辑,可以在事务的特定阶段执行。
流程如下:
- 客户端代码请求事务管理器开始一个事务。
- 事务管理器在
TransactionSynchronizationManager
中注册TransactionSynchronizationAdapter
。 - 客户端执行事务性工作。
- 事务完成后,客户端请求事务管理器提交或回滚事务。
- 如果是提交,
TransactionSynchronizationAdapter
的beforeCommit
方法将被触发。 - 客户端的自定义逻辑在提交前执行。
- 事务提交后,
TransactionSynchronizationAdapter
的afterCommit
方法被触发。 - 客户端的自定义逻辑在提交后执行。
- 不论是提交还是回滚,
TransactionSynchronizationAdapter
的afterCompletion
方法都会被触发。 - 客户端的自定义逻辑在事务完成后执行。
时序图:
在时序图中,以下步骤:
- 客户端代码请求事务管理器开始一个新事务。
- 事务管理器向
TransactionSynchronizationManager
注册TransactionSynchronizationAdapter
。 - 客户端执行事务性工作。
- 事务性工作完成后,客户端请求提交事务。
- 如果事务提交,事务管理器将调用
TransactionSynchronizationAdapter
的beforeCommit()
方法,然后是afterCommit()
方法。 - 如果事务回滚,事务管理器将调用
TransactionSynchronizationAdapter
的beforeCompletion()
方法。 - 无论事务提交还是回滚,事务管理器都会调用
TransactionSynchronizationAdapter
的afterCompletion(status)
方法。 - 客户端代码接收到事务结束的通知。
在 TransactionSynchronizationAdapter
的每个方法中,可以执行自定义逻辑,如在提交前验证数据,在提交后发送通知,或在事务完成后清理资源。
封装工具类:
typescript
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.reactive.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
/**
* @Author derek_smart
* @Date 2024/5/31 10:10
* @Description
* <p> TransactionSynchronizationAdapter 工具类
*/
@Slf4j
public class TransactionManageService {
private static ExecutorService defaultExecutorService = Executors.newCachedThreadPool();
public static <T> void afterCommitDefault(T args, Consumer<? super T> consumer) {
afterCommit(args, consumer, defaultExecutorService);
}
public static void setDefaultExecutorService(ExecutorService executorService) {
defaultExecutorService = executorService;
}
/**
* 添加钩子来跟踪异步操作的性能。
* @param args
* @param consumer
* @param executorService
* @param <T>
*/
public static <T> void afterCommit(T args, Consumer<? super T> consumer, ExecutorService executorService) {
Objects.requireNonNull(consumer, "Consumer must not be null");
Objects.requireNonNull(executorService, "ExecutorService must not be null");
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
executorService.submit(() -> {
long startTime = System.currentTimeMillis();
try {
consumer.accept(args);
} catch (Exception e) {
log.error("Error executing afterCommit", e);
} finally {
long duration = System.currentTimeMillis() - startTime;
log.info("afterCommit executed in {} ms", duration);
}
});
}
}
);
}
/**
*
* @param args
* @param consumer
* @param executorService
* @param errorMsg
* @param <T>
*/
public static <T> void afterCommit(T args, Consumer<? super T> consumer, ExecutorService executorService, String errorMsg) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
executorService.submit(() -> {
try {
consumer.accept(args);
} catch (Exception e) {
log.error(errorMsg, e);
}
});
}
}
);
}
/**
*
* @param args
* @param consumer
* @param <T>
*/
public static <T> void afterCommit(T args, Consumer<? super T> consumer) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
consumer.accept(args);
}
}
);
}
/**
*
* @param runnable
* @param executorService
* @param <T>
*/
public static <T> void afterCommit(Runnable runnable, ExecutorService executorService) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
executorService.submit(() -> {
try {
runnable.run();
} catch (Exception e) {
log.error("run fail", e);
}
});
}
}
);
}
/**
* 增加事务回滚后的操作支持
*
* @param args
* @param consumer
* @param <T>
*/
public static <T> void afterRollback(T args, Consumer<? super T> consumer) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCompletion(int status) {
if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
consumer.accept(args);
}
}
});
}
// 在事务提交后执行给定的操作
public static void afterCommit(Runnable action) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
action.run();
}
});
}
// 在事务回滚后执行给定的操作
public static void afterRollback(Runnable action) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCompletion(int status) {
if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
action.run();
}
}
});
}
// 在事务提交后执行给定的操作,并消费事务结果
public static <T> void afterCommit(Consumer<T> action, T result) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
action.accept(result);
}
});
}
// 在事务回滚后执行给定的操作,并消费事务结果
public static <T> void afterRollback(Consumer<T> action, T result) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCompletion(int status) {
if (status == TransactionSynchronization.STATUS_ROLLED_BACK) {
action.accept(result);
}
}
});
}
}
使用这个工具类的例子:
java
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class MyTransactionalService {
@Transactional
public void executeWithTransaction() {
// 执行一些事务操作...
// 注册事务提交后的操作
TransactionUtils.afterCommit(() -> System.out.println("Transaction committed successfully!"));
// 注册事务回滚后的操作
TransactionUtils.afterRollback(() -> System.out.println("Transaction rolledback!"));
}
}
以上类为自己总结写,由时间原因故此不再详细介绍如何使用,后续有空继续。
总结:
总之,TransactionSynchronizationAdapter
提供了一种强大的机制来扩展 Spring 事务的行为。当使用得当时,它可以增强应用程序的事务管理能力,但也需要注意其带来的依赖和潜在的性能影响。