在開發(fā)過程中大家一定遇到過一種業(yè)務(wù)場景毁靶,需要在事務(wù)執(zhí)行結(jié)束后再執(zhí)行的代碼邏輯梗夸,這個(gè)代碼不受事務(wù)成敗與否的影響,spring也為我們提供了這種功能那就是TransactionSynchronization孩革。
為了方便使用我們直接封裝成一個(gè)工具類,使用ThreadLoal對方法與線程進(jìn)行綁定案铺。
package com.casa.leetcode.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
/**
* 用于處理一些必須要等待事務(wù)提交后執(zhí)行的操作
*
* save操作整個(gè)流程鏈
* - 2022-08-16 10:04:15,586 [http-nio-8089-exec-1] ERROR c.c.l.u.TransactionLifeCycleUtils - TransactionLifeCycleUtils --- beforeCommit
* - 2022-08-16 10:04:15,586 [http-nio-8089-exec-1] ERROR c.c.l.u.TransactionLifeCycleUtils - TransactionLifeCycleUtils --- beforeCompletion
* - 2022-08-16 10:04:15,648 [http-nio-8089-exec-1] ERROR c.c.l.u.TransactionLifeCycleUtils - TransactionLifeCycleUtils --- afterCommit
* - 2022-08-16 10:04:15,648 [http-nio-8089-exec-1] ERROR c.c.l.u.TransactionLifeCycleUtils - TransactionLifeCycleUtils --- afterCompletion --- 0
*
*/
@Slf4j
public class TransactionLifeCycleUtils {
private static ThreadLocal<List<Runnable>> threadLocalRunnableList = new ThreadLocal<>();
private static TransactionSynchronization action = new TransactionSynchronization() {
@Override
public void afterCompletion(int status) {
if (status == STATUS_COMMITTED) {
List<Runnable> runnableList = threadLocalRunnableList.get();
threadLocalRunnableList.remove();
runnableList.forEach(Runnable::run);
}
TransactionSynchronization.super.afterCompletion(status);
}
};
/**
* 單例
* @param command
*/
public static void afterCommitSuccessCallback(Runnable command) {
ThreadLocal<List<Runnable>> local = threadLocalRunnableList;
Optional.ofNullable(local.get()).ifPresentOrElse(
list -> list.add(command),
() -> {
LinkedList<Runnable> list = new LinkedList<>();
list.add(command);
local.set(list);
TransactionSynchronizationManager.registerSynchronization(action);
}
);
}
}
那我們?nèi)绾问褂媚?/p>
@Transactional
public Object save(SystemConfig config){
TransactionLifeCycleUtils.afterCommitSuccessCallback(
() -> log.info("save jpa success.")
);
return repository.saveAndFlush(config);
}
再說說如果不使用TransactionSynchronization我們想在事務(wù)之外執(zhí)行代碼是怎么實(shí)現(xiàn)的务嫡。
public void saveConfig(SystemConfig config){
this.save(config);
//事務(wù)之外的邏輯
log.info("save jpa success.")
}
@Transactional
public Object save(SystemConfig config){
return repository.saveAndFlush(config);
}
有問題歡迎討論i?