可以用TransactionSynchronizationAdapter 这个类,
public abstract class TransactionSynchronizationAdapter implements TransactionSynchronization, Ordered {
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
public void suspend() {
}
public void resume() {
}
public void flush() {
}
public void beforeCommit(boolean readOnly) {
}
public void beforeCompletion() {
}
public void afterCommit() {
}
public void afterCompletion(int status) {
}
}
TransactionSynchronizationAdapter 会根据事务的完成状态去调用相应的afterCommit等
定义拦截方法注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AfterCommit {
}
定义切面
@Aspect
public class AfterCommitAnnotationAspect {
private static final Logger LOGGER = Logger
.getLogger(AfterCommitAnnotationAspect.class);
private final AfterCommitExecutor afterCommitExecutor;
@Autowired
public AfterCommitAnnotationAspect(AfterCommitExecutor afterCommitExecutor) {
this.afterCommitExecutor = afterCommitExecutor;
}
@Around(value = "@annotation(com.best.oasis.spring.transaction.AfterCommit)", argNames = "pjp")
public Object aroundAdvice(final ProceedingJoinPoint pjp) {
afterCommitExecutor.execute(new PjpAfterCommitRunnable(pjp));
return null;
}
private static final class PjpAfterCommitRunnable implements Runnable {
private final ProceedingJoinPoint pjp;
public PjpAfterCommitRunnable(ProceedingJoinPoint pjp) {
this.pjp = pjp;
}
@Override
public void run() {
try {
pjp.proceed();
} catch (Throwable e) {
LOGGER.error("Exception while invoking pjp.proceed()", e);
throw new RuntimeException(e);
}
}
@Override
public String toString() {
String typeName = pjp.getTarget().getClass().getSimpleName();
String methodName = pjp.getSignature().getName();
return "PjpAfterCommitRunnable[type=" + typeName + ", method=" + methodName + "]";
}
}
}
执行器
public interface AfterCommitExecutor extends Executor {
}
执行器实现,真正调用的地方
@Service
public class AfterCommitExecutorImpl extends TransactionSynchronizationAdapter implements AfterCommitExecutor {
private static final Logger LOGGER = Logger.getLogger(AfterCommitExecutorImpl.class);
private static final ThreadLocal<List<Runnable>> RUNNABLES = new ThreadLocal<List<Runnable>>();
@Override
public void execute(Runnable runnable) {
LOGGER.info("Submitting new runnable {"+runnable+"} to run after commit");
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 {"+threadRunnables.size()+"} runnables" );
for (int i = 0; i < threadRunnables.size(); i++) {
Runnable runnable = threadRunnables.get(i);
LOGGER.info("Executing runnable {"+runnable+"}");
try {
runnable.run();
} 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();
}
}