基于Spring事务模板编程式事务小工具
写在前面
基于Spring事务,官方推荐使用@Transactional注解的声明式事务,使用便捷,无需关心底层实现,只需关心注解中的参数含义及使用规则。
然而在很多场景下(特别是复杂的业务逻辑、更甚在子线程、多线程中),往往声明式事务会出现意想不到的结果。这时候针对特定场景,这时编程式事务更加得心应手。
代码实现
以下是一个简版的小工具,没有太复杂的场景基本可以满足
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;/*** Spring 编程时事务帮助类* <p>* 执行时可根据需求设置传播行为或隔离级别TransactionDefinition* 传播行为:{@link TransactionTemplate#setPropagationBehavior(int)} 参数来自默认:{@link TransactionDefinition#PROPAGATION_REQUIRED}* 隔离级别(慎重,除特殊情况外,推荐保持默认):{@link TransactionTemplate#setIsolationLevel(int)} (int)} 参数来自默认:{@link TransactionDefinition#ISOLATION_DEFAULT}**/
@Component
public class TransactionHelper {private final TransactionTemplate transactionTemplate;/*** 存储初始化 TransactionTemplate 时的传播机制和隔离级别*/private final static int[] INITIALIZE_TRANSACTION_TEMPLATE_PROPS = new int[2];public TransactionHelper(@Nullable PlatformTransactionManager platformTransactionManager) {this.transactionTemplate = new TransactionTemplate(platformTransactionManager);INITIALIZE_TRANSACTION_TEMPLATE_PROPS[0] = this.transactionTemplate.getPropagationBehavior();INITIALIZE_TRANSACTION_TEMPLATE_PROPS[1] = this.transactionTemplate.getIsolationLevel();}/*** 执行带返回的事务回调** @param callback - 不带返回值回调*/public static void executeWithoutResult(@NonNull ICallFunc callback) {executeWithoutResult(callback, TransactionDefinition.PROPAGATION_REQUIRED);}/*** 执行带返回的事务回调** @param callback - 不带返回值回调* @param propagationBehavior - 事务传播行为(通过{@link TransactionDefinition}获取)*/public static void executeWithoutResult(@NonNull ICallFunc callback, int propagationBehavior) {executeWithoutResult(callback, propagationBehavior, TransactionDefinition.ISOLATION_DEFAULT);}/*** 执行带返回的事务回调** @param call - 不带返回值回调* @param propagationBehavior - 事务传播行为(通过{@link TransactionDefinition}获取)* @param isolationLevel - 事务隔离级别(通过{@link TransactionDefinition}获取)*/public static void executeWithoutResult(@NonNull ICallFunc call, int propagationBehavior, int isolationLevel) {final TransactionTemplate template = getInstance().getTransactionTemplate();try {template.setPropagationBehavior(propagationBehavior);template.setIsolationLevel(isolationLevel);template.executeWithoutResult(status -> call.call());} finally {if (!(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[0] == template.getPropagationBehavior()&& INITIALIZE_TRANSACTION_TEMPLATE_PROPS[1] == template.getIsolationLevel())) {synchronized (INITIALIZE_TRANSACTION_TEMPLATE_PROPS) {template.setPropagationBehavior(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[0]);template.setIsolationLevel(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[1]);}}}}/*** 执行带返回的事务回调** @param callback - 带返回值回调* @param <T> - 返回类型*/public static <T> T execute(@NonNull ICallBackFunc<T> callback) {return execute(callback, TransactionDefinition.PROPAGATION_REQUIRED);}/*** 执行带返回的事务回调** @param callback - 带返回值回调* @param propagationBehavior - 事务传播行为(通过{@link TransactionDefinition}获取)* @param <T> - 返回类型*/public static <T> T execute(@NonNull ICallBackFunc<T> callback, int propagationBehavior) {return execute(callback, propagationBehavior, TransactionDefinition.ISOLATION_DEFAULT);}/*** 执行带返回的事务回调** @param callback - 带返回值回调* @param propagationBehavior - 事务传播行为(通过{@link TransactionDefinition}获取)* @param isolationLevel - 事务隔离级别(通过{@link TransactionDefinition}获取)* @param <T> - 返回类型*/public static <T> T execute(@NonNull ICallBackFunc<T> callback, int propagationBehavior, int isolationLevel) {TransactionTemplate template = getInstance().getTransactionTemplate();try {template.setPropagationBehavior(propagationBehavior);template.setIsolationLevel(isolationLevel);return template.execute(status -> callback.call());} finally {if (!(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[0] == template.getPropagationBehavior()&& INITIALIZE_TRANSACTION_TEMPLATE_PROPS[1] == template.getIsolationLevel())) {synchronized (INITIALIZE_TRANSACTION_TEMPLATE_PROPS) {template.setPropagationBehavior(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[0]);template.setIsolationLevel(INITIALIZE_TRANSACTION_TEMPLATE_PROPS[1]);}}}}protected static TransactionHelper getInstance() {return SpringUtil.getBean(TransactionHelper.class);}protected TransactionTemplate getTransactionTemplate() {return this.transactionTemplate;}@FunctionalInterfacepublic interface ICallFunc {void call();}@FunctionalInterfacepublic interface ICallBackFunc<R> {R call();}
}