1

I have a table of data and I can create , update and delete rows. I have apis to do these operations. The following steps happen

  1. I create a row and send a create request to server.
  2. I update some values in the row and send an update request before the response of create has come.
  3. In server since the create row has not completed, the update cannot continue.

How do I handle this situation? Should I make an update request only after success of create? Should I queue the request on server?

If the create fails, should I remove the rows on client? or should I retry the request? Need help on how to deal with this. Thanks

  • Your server API appears to be subject to race conditions. A similar situation to what you're describing here can also arise with multiple users. – Erik Eidt Dec 21 '17 at 16:23
2

Well, the simplest solutions would be either sequence the operations on the client-side, by waiting for the creation to return before sending the update, or send both operations in a single command so they can be sequenced on the server side.

It's hard to recommend specific approached because you haven't really told us much about your requirements, i.e. do you have performance requirements that are not met if you wait for the creation response before sending the update?

If the create fails, should I remove the rows on client? or should I retry the request?

Again this depends on your requirements and the reason for the failure. If the failure was due to a network timeout then retrying might make sense, but if it was due to invalid data than retrying would be pointless...

1

Asynchronous approach

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.

Queue approach

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.

Transactions

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.

Conclusion

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.

0

Guess what ? databases use a journal to sequentially note down the changes as they come in from multiple sources.

You can have one such construct locally where a change from UI can enqueue a request (Create,Update,Delete). Another worker can consume this journal and transact each request with server in same order. When this queue is empty, all changes are saved.

Imagine a stream of commands that modify a remote resource , where each command can precisely locate a remote resource and the the nested fields in it, convey whether to add or remove and carry the new value:

+ tables/001/ [0.name] = "joe"
- tables/003/ [2]
- tables/001/ [3.age]
+ tables/002/ [0.age]  = 23
+ cars/009    [model]  = "chevy" 

You can use 2-way socket connection to the resource being edited and send/receive such changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.