1

I make a request to a REST API (let it be API 1) which internally calls another 2 APIs (APIs 2 & 3) synchronously.

API 1 = REST API

API 2 = Pre-signed url to upload a file into S3

API 3 = A DB update (SQL Server)

API 3 i.e., the DB update will be made only if the file is successfully uploaded (API 2) into S3.

In case the DB update (API 3) is failed, the changes API 2 did should be rolled back i.e., the uploaded file should be deleted in S3.

Please advise how to handle this scenario. Any out-of-the-box solution is welcome.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
MAK
  • 1,915
  • 4
  • 20
  • 44

2 Answers2

2

S3 services are not transactional. Basically all the rest apis are not transactional so all the operations are atomic: What are atomic operations for newbies?

What this means is that you can't rollback the operation if it has succeeded.

  1. It would be easy to say that it's ok. Once local db fails I can issue a delete call on s3 to delete my file. But what happens if this fails too?

  2. Another way would be to first write to your database and then post the file. Again if the file upload fails you can rollback the db command. That is safer, but still... what happens when you send the request but you get a timeout? The file might be on the server but you just won't know.

Enter the world of eventual consistency.

While there are ways to mitigate the issue with retries (check polly library for test retries) what you can do is store the action.

You want to upload the file. Add it to a queue and run the task. Mark the task as failed. Retry as many times as you want and mark the failure reasons.

Here comes manual interventions. When all else fails, someone should intervene with some resolution strategy.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
2

If you need to "undo" an upload to any file system (S3 is a file system) you do it like this.

  1. Upload the new file with some temporary unique file name (a guid will do fine).
  2. To "commit" the upload, remove the file you're replacing and rename the one you just uploaded so it has the same name as the old one.
  3. To "roll back" the upload, remove the temp file.

An even better way, if your application allows it, is to give each version of the file a different name. Then you just upload each new one with its own name, and clean up by deleting the old ones.

In your particular scenario, it might make sense to do your database update operation first, and the upload second, if that won't open you up to a nasty race condition.

O. Jones
  • 103,626
  • 17
  • 118
  • 172
  • Again, what happens if you fail at step 3 and the rename fails? And for your second recommendation, what happens if you get a timeout but the file has uploaded? – Athanasios Kataras Feb 19 '21 at 17:13