I am using C#.NET Web API for my iOS application but I have concerns about multiple requests arrive at the same time.
Let's assume I try to prevent duplicating records while inserting a new record into Users table by:
Check if xxx#example.com exists in the Users table.
Insert if not exists.
Return OK.
Actually it's that simple unless web api runs async.
What if related web api method gets two requests at the same time (with same e-mail request) and when the first request reaches step 2 (but not executed yet) and second request will get "not exists" response since step two for first request has not been executed yet. Then two e-mail address will be saved and I will have duplicated records.
Using lock on static object seems will solve the problem but it will create performance issues.
If I don't want DB to get rows duplicated, how can I overcome by that problem?
UPDATE:
I can't use unique constraint on e-mail column due to I already have it on Id column.
If you make the email address in your table have a unique constraint then all you have to do is insert the email address, if it already there it will fail, if not you will have inserted a new record.
You need to handle the failure maybe respond with some appropriate code to the client so it knows email already exists.
Related
Based on the examples from the Internet I made this database, but I have some problems using it
How should I add ExtraItem to the order?
For example if I put in my orders a food item then I send a POST request to the server which returns a new created entry. What should I do next in order to add an Extra to that order? I have FoodItemExtraId but I don't know the OrderFoodItemId to make a POST request to OrderFoodItemExtra table.
Or maybe this schema is not correct?
Following JSON in the Body of a PUT request will not create a record but will update a record if one already exists. Any insights as to why are greatly appreciated
Request returns Error 500 Internal Server Error. Internal Message is null.
Destination System is 2020R1 and NetFramework vs. 4.7.2
API Endpoint is Default 18.200.001
{"EmployeeID":{"value":"010"},"Status":{"value":"Inactive"},"EmployeeName":{"value":"Johnson, Samuel"},"Contact":{"FirstName":{"value":"Samuel"},"MiddleName":{"value":"D"},"LastName":{"value":"Johnson"},"Email":{"value":"sjohnson#some-eco.com"},"DateOfBirth":{"value":"1993-05-11T00:00:00"},"Address":{"AddressLine1":{"value":"961 Flora Dr."},"AddressLine2":{"value":null},"City":{"value":"Shreveport"},"Country":{"value":"US"},"State":{"value":"LA"},"PostalCode":{"value":"71106"}}},"EmployeeSettings":{"EmployeeRefNbr":{"value":"010"},"EmployeeClass":{"value":"STANDARD"},"BranchID":{"value":"AEL.ADMIN"},"DepartmentID":{"value":"ADMIN"},"Calendar":{"value":"STANDARD"},"LaborItem":{"value":"LABOR"}}}
Successfully Updated OK
Failed Created
enter image description here
IF you are using the same json to create a new record there will be trouble ofcourse, because EmployeeId is a primary key and can not be inserted(you should check if your table has automatic identity increase) also check with your table constrains like (foreign keys).
if those were not the problem, please provide the code you are using.
An app makes an HTTP post with Idempotency Key in the API request header.
On the server-side, you want to check if the request with the Idempotent Key has been processed for this client or not.
If the request has not been processed than we proceed with the method to CREATE, UPDATE or DELETE.
If the Idempotent Key has been used in the previous request, then we response back to the client with an error message.
How do we track the API request, the API count, and the Idempotent Key used in request etc?
By logging all API request in the database and make a round trip to the database to check this information everytime a new request is made? Or is there a better way?
You can try to use this open source component on github to solve your problem IdempotentAPI
What I like doing in a fairly standard setup (database, EF core, web api) is use a middleware to add (Context.Add()) the idempotency key to the database without committing.
Later on, in the controller, a service or some sort of handler, I make sure Context.SaveChanges() (or UnitOfWork.Commit()) is called only once (which should normally be the case since you’re supposed to update only 1 aggregate root per transaction).
This way you’re sure you’re saving atomically, your idempotency key will only be saved if your insert/update/delete is successful. If the idempotency key already exists in the database your insert/update/delete will fail.
Finally, what you can also do is cache your successful responses, so that in case of idempotency exception, you can simply return the cached response.
We are using the Partner WSDL in our C# integration with Salesforce and we are receiving the following error when trying to update more than 200 records:
Error updating Contact: EXCEEDED_ID_LIMIT: record limit reached. cannot submit more than 200 records into this call
How do we go about increasing this number? Is it possible or are we stuck with 200 records?
Thanks ahead of time for your resonse.
You can only update 200 records in a single request, you need to chunk your update up into sets of 200 and make multiple calls.
The web service administrators have probably limited each call to 200 records as a safeguard. This means less load on their servers and quicker response to the client.
You probably cannot change this limit unless you contact the web service administrator directly.
For now you should keep the limit in mind and make multiple requests of 200 records each instead of a single request.
Note: Web services that limit the number of records returned per request will sometimes return an ID number. This usually allows the client to continue picking up records where they left off. Keep an eye out for this.
I've got several web-services: asmx,wcf. At couple of them there are some methods, which take a lot of time for processing, but size of input data for these methods are small and it takes not much time to transfer on the wire. I want move to not sync model. Client passes data to service, service answers that data transfer was correct and process it at background thread witout connection with client. So agter transfering connection should be closed. IS it possible? Can u help me with articles or may be just google request.
John is right - Once you close an http connection, it is done. You can't get back to the same process.
So if you can use another technology that allows duplex on one connection (e.g. WCF), do it!
However,
if you have no choice but to use webservices,
here are three ways to make it work. You may get timeouts on any of them.
Option 1:
Forget the part about 'client answers data was correct.' Just have each thread make its request and wait for the data.
Option 2:
Now, assuming that won't work and you must do the validation, this way requires the client to make 2 requests.
First request: returns valid/invalid.
Second request: returns the long-running results.
Variation of option 2:
If you have timeout problems, you could have the first request generate a GUID or unique database key and start another process, passing it this key, and return the key to the client. (if you can get the server to allow you to start a process - depends on security settings/needs - if not you may be able to start an async thread and have it keep running after the websvc one ends?) The process will do the long task, update the row in the database w/ the unique id when finished, revealing the results plus a 'done' flag. The second request by the client could always return immediately and if the processing is not done, return that, if it is, return the results. The client will repeat this every 5 sec or so until done.
Hacks, I know, but we don't always have a choice for the technology we use.
Don't do this with ASMX web services. They weren't designed for that. If you must do it with ASMX, then have the ASMX pass the data off to a Windows Service that will do the actual work, in the background.
This is more practical with WCF.
We have been writing stuff to interact with the UK gov website and the way they handle something similar is that you send your request and data to the server and it responds saying, roughly, "thanks very much - we're processing it now, please call back later using this id" - all in an XML message. You then, at some point later, send a new http request to the service saying, essentially, "I'm enquiring about the status of this particular request id" and the server returns a result that says either it has processed OK, or processed with errors, or is still processing, please try again in xx seconds.
Similar to option 2 described previously.
It's a polling solution rather than a callback or 2 way conversation but it seems to work.
The server will need to keep, or have access to, some form of persistent table or log for each request state - it can contain eg, the id, the original request, current stage through the workflow, any error messages so far, the result (if any) etc. And the web service should probably have passed the bulk of the request off to a separate Windows service as already mentioned.