Traditionally, an API responsible for performing an asychronous task like creating a row in the database must provide a means to communicate success or failure. You can do this in two ways:
- Via callback - meaning an instance of an interface you can call on success or failure
- Via a promise - which is a value returned immediately upon call which blocks when you need the value (the process runs in parallel until you need the value contained within).
The caller can then deal with the promise or callback accordingly. If multiple calls are potentially needed, you must guarantee that one has finished before calling the next.
This approach means granting more responsibility to your backend. The caller no longer cares about whether or not the task is finished. Your api does. Meaning you must guarantee that the tasks are executed in the order of their call. This can be done easily enough by adding requests into a queue. First entries are processed first and only once each previous task has finished.
In both cases, you must prepare for the possibility of multiple threads accessing the same record. In other words, it could still happen that process A deletes row 1 to prepare to be reinserted, and process B attempts to update row 1 shortly thereafter. This type of problem is normally dealt with by using transactions, which is to say, you have a series of actions collected into a single transaction. Your API must guarantee that all will be executed or none of them will be.
This can be done by ordering the transactions themselves. With each call to the API under a given transaction, that transaction grows 1 operation. Nothing is done until the order is given to commit that transaction, and the proper execution order of transactions is based on the creation of said transaction. This is to ensure that the effects of future transactions will not be seen by the current.
You must be able to execute all actions of one transaction with a means to reverse each operation. If failure occurs halfway through, you must reverse every successful process up to that point. If transaction succeeds, the effects of your changes must be visible on your database. If you're using a single thread to apply these changes, nothing more is necessary to make changes visible because your transaction order guarantees it. However, if you use multiple threads for this, you will have to ensure that any other transaction cannot see the effects of the transaction being executed until the very end.
Books have been written on this subject, as this is really not so different from how databases work and how data modification requests are executed. This really lightly skims over the subject, but hopefully it gives you enough to work with.