Spring @Transactional 不适用于第三方 API 调用

Spring @Transactional doesn't work with third party API call

我正在开发Spring-启动应用程序,服务层有文件上传功能这是代码片段-

@Transactional(rollbackOn = AmazonServiceException.class)
@Override
public Post createPost(PostEntity postEntity, MultipartFile attachments) {
    uploadOnS3(postEntity.getPostMedia(), attachments); // push into s3 bucket
    .....
    ....
    postRespository.save(postEntity);//store into application databse
}

问题场景:

  1. 假设文件已成功上传到 s3 存储桶及其 return 文件 url

  2. 下一步发生异常,事务已滚动 支持

  3. 因为文件已经上传,所以应用程序不会有 任何信息

到目前为止我尝试过的:

  1. 我已经绑定到在 s3 存储桶上传之前插入本地数据库的东西,但我没有 得到任何回调,比如本地数据库插入已经完成,现在我们应该 启动 s3 任务。

  2. 同时我还要通知客户关于 状态

spring是否提供任何机制让我们知道本地数据库插入已经完成?或者有没有更好的方法来处理这种情况?

本质上第三方API不能成为spring交易的一部分。您可以选择以下方法之一。所有这些方法都各有利弊,因此您必须根据最适合自己的方式进行选择 -

  1. 使用 ThreadLocal 保存 postEntity 对象(或任何其他已上传文件信息的对象)。在你的错误处理例程中,检查这个对象并用它做任何你想做的事。如果没有错误,那么这已经在数据库中了。请确保适当地清理 threadlocal 值,以确保它可以在多次调用中安全使用。
  2. 使用 Annotation-Driven Event Async Listener 并将此侦听器标记为事务性。这样,即使主事务发生故障,对象也将使用单独的事务保存在数据库中。您可能希望在主流程中执行此操作,或者您可以选择在错误处理例程中执行此操作(比如从 threadlocal 中提取实体对象)。
  3. 使用 Transaction Bound Events 并将其绑定到 AFTER_ROLLBACK 阶段。仅当事务已回滚时才会触发此事件。这可能会简化您的用例,因为这将避免 ThreadLocal 类型的中间存储。