Spring代码实现:
package xxxx.components;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 事务完成之后再执行操作
*/
@Slf4j
@Component
public class AfterCommitExecutor extends TransactionSynchronizationAdapter implements Executor {
Logger logger = LoggerFactory.getLogger(this.getClass());
private static final ThreadLocal<List<Runnable>> RUNNABLES = new ThreadLocal<List<Runnable>>();
private ExecutorService threadPool = Executors.newFixedThreadPool(5);
@Override
public void execute(Runnable runnable) {
logger.info("Submitting new runnable {} to run after commit", runnable);
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
logger.info("Transaction synchronization is NOT ACTIVE. Executing right now runnable {}", runnable);
runnable.run();
return;
}
List<Runnable> threadRunnables = RUNNABLES.get();
if (threadRunnables == null) {
threadRunnables = new ArrayList<Runnable>();
RUNNABLES.set(threadRunnables);
TransactionSynchronizationManager.registerSynchronization(this);
}
threadRunnables.add(runnable);
}
@Override
public void afterCommit() {
List<Runnable> threadRunnables = RUNNABLES.get();
logger.info("Transaction successfully committed, executing {} runnables", threadRunnables.size());
for (int i = 0; i < threadRunnables.size(); i++) {
Runnable runnable = threadRunnables.get(i);
logger.info("Executing runnable {}", runnable);
try {
threadPool.execute(runnable);
} catch (RuntimeException e) {
logger.error("Failed to execute runnable " + runnable, e);
}
}
}
@Override
public void afterCompletion(int status) {
logger.info("Transaction completed with status {}", status == STATUS_COMMITTED ? "COMMITTED" : "ROLLED_BACK");
RUNNABLES.remove();
}
}
二、调用
@Service
@Trasaction
public class TestService {
@Autowired
private AfterCommitExecutor afterCommitExecutor;
public void test() {
//TODO 业务功能处理
//各种 save 、update、delete操作
//事务提交后执行
afterCommitExecutor.execute(new Runnable() {
@Override
public void run() {
//TODO 事务提交后功能
}
});
}
}