事务回滚后从文件系统中删除文件

Remove file from filesystem after transaction rollback

在事务方法的Spring应用程序中,数据应该被持久化并且文件被写入文件系统(带有路径和文件名)。现在,如果数据库事务由于某种原因失败,文件将再次从文件系统中删除。

为此,我考虑使用如下事件侦听器。

@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleRollback() {
    // remove file with the use of the path and file name 
    // (but where do those two parameters come from?)
}

但是,在该事件侦听器中,我需要路径的属性 valuefileName 才能知道要删除哪个文件。但我认为导致回滚的事件将由 Spring 触发,我无法随它传递值。

那么我该如何处理回滚?

您可以尝试以下架构:

@Service
class DbService {
   @Transactional
   public void doInDb() {}
}

@Service
class DomainService {
    @Autowired DbService dbService;
    @Autowired FsService fsService;
    ...
    public void doDbAndFs() {
       try {
         fsService.saveFiles();
         dbService.doInDb();
       } catch (Exception e) {
          fsService.cleanUp();
       }

    }
}

所以你在没有事务上下文的情况下进行 FS 更改。如果在事务上下文中发生某些异常,您将捕获它并让 FS 清理。

标准解决方案似乎按如下方式工作。包含回滚所需的所有数据的事件始终从事务方法发布。只有在回滚的情况下才会调用侦听器。

@Transactional
public void executeTransactionCode(final Long id) {
    MyRollbackEvent myRollbackEvent = ... create the event with the necessary data ...
    applicationEventPublisher.publishEvent(myRollbackEvent);
    executeDBCode();
}

和回滚事件监听器

@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleRollback(final MyRollbackEvent event) {
    // code to handle rollback, data now available through the event
}

即使侦听器因异常而失败,回滚仍在执行。