如何评估服务器请求/数据库插入的成功

I have an app that talks to the server like this:

  1. The app sends a request to a server
  2. The server inserts data into a database
  3. The server sends a JSON object to the app with various data

If the app does not get a valid JSON object back, it assumes there must be a network error and creates a timer which tries to re-send the request after some time.

However, I have noticed that sometimes the request gets inserted twice into the database, probably because the initial request was inserted, but then the script failed to generate a JSON object (possibly because the script crashed or timed out half-way in), and then the app thinks "Hey, my request failed, I must try again", and then it sends a second request even though the first one was actually inserted, and you end up with duplicates.

I thought maybe I could check for a non-OK HTTP status, but if I provoke a fatal error in PHP, the server still returns a "HTTP 200 OK" status.

query("insert into blah values (...");
non_existent_function();
generate_response();

Is there any way I can get a HTTP error status back upon a crashed or timed-out PHP script?

Or other advice on how the client can do as good as possible an assessment of whether a request was successful?

If the problem is only in execution time maybe you can raise it from the php script.

ini_set('max_execution_time', 300); //300 seconds = 5 minutes

But then again the app still wont know if its realy succesfull.

How can you get invalid JSON object by network error? Assuming that you use HTTP, the connection is managed on the Transportation Layer by TCP, which is a bidirectional, reliable byte-stream. If you receive some data from the server, than it's checked with CRC32, duplicates are managed and lost segments are forced to be sent again by GoBack-N.

TCP deals with everything, so when you find an invalid JSON object on your device, it must be caused by a malfunctioned process on the server. An invalid JSON or processing error could be realized on the server before sending the response to the device. You must identify the error on the server! Just roll back the database operation, and send an error message back to the device, so it could initiate the command again, if it would like to do so.

Okay. What if the server successfully processed your request and the connection get lost before the device would receive the response. The device must be warned about this, because TCP was not able to close the connection normally! So, the device knows, that it sent (or maybe not) a request but didn't receive a response. What the device doesn't know that, its request has been successfully processed or an error has been raised.

Too bad. You are in the Application Layer, and you must deal with this. I would create an identification for each request and store it on the server. When the device sends the same command with the same identification, the server would only send back a response something like this: "already done boss". This is similar how TCP deals with this, but on the Transport Layer. Store the identification as long as you would like to - but I think you can delete it if the TCP connection was successfully closed: the device received the response.