1. Spring 事务相关
1.1 事务提交前后的额外处理
应用场景:当我们使用 spring 的事务系统控制事务时,若需要在事务提交之前或者之后做一些额外的处理(比如解锁,打印日志),此时就可以使用TransactionSynchronizationManager这个类结合TransactionSynchronization类来实现。
实现的方法:通过TransactionSynchronizationManager.registerSynchronization()方法,入参传入一个TransactionSynchronization类型的对象,重写该对象的部分方法,那么spring在事务提交前后,就会去执行入参中传入的TransactionSynchronization类型中重写的相应方法。
具体代码例子:
// 写一个开启了事务的方法,在执行数据库操作前调用TransactionSynchronizationManager.registerSynchronization()方法
@Override
@Transactional(rollbackFor = RuntimeException.class)
public int updateTest(UpdateUserVO userVO) {
commitDeal(); // 这里传入要执行操作
User user = User.builder().build();
user.setId(new Random().nextLong());
userDao.updateById(user);
return userDao.updateById(user);
}
private void commitDeal() {
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization(){
// 这里就是相应的事务提交前后会执行的方法
@Override
public void beforeCommit(boolean readOnly) {
log.debug("事务提交前处理...");
}
@Override
public void beforeCompletion() {
log.debug("事务提交/回滚前处理...");
}
@Override
public void afterCommit() {
log.debug("事务提交完成处理,此时事务仍处于活动状态...");
}
@Override
public void afterCompletion(int status) {
log.debug("事务提交或回滚完成处理,此时事务仍处于活动状态...", status);
}
}
);
}
执行结果:
总结
- 要在开启事务的方法中注册事务提交/回滚处理,否则会报错:Transaction synchronization is not active
- afterCommit和afterCompletion方法的区别在于:一个只有提交时才会调用,一个是提交和回滚都会调用。
- afterCommit和afterCompletion方法中,如果要再次进行数据库操作,一定要重新开启一个事务,否则有可能使用当前已提交/回滚,但是尚未关闭的事务,导致出现问题。