New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
atomic operation issue #98
Comments
In this case it would be better to specify your own recordID when creating a new record. If you make sure that it represents your primary key (probably the field that you use in your check) then you could insert your data without validating it first. If the recordID already exists, then you will end up in the failure handler and you can react on that (fetch and update or report an error). |
In my case, users submit their reading books, there are 2 tables: book(title, author) and reading(who, when book_reference). Steps are: check book existence -> yes, insert reading using existed bookid; no, insert a new book and insert reading using this new bookid. One day, 2 users submit the same book at almost same moment, 2 the same books will submitted. This is the issue for all case of insertion according to existence. How to ensure the record uniqueness using cloudkit? |
CloudKit keeps a version number with every record. So if both user A and B read from CloudKit and they will both get version X, Then whoever saves first kan just save it because the record will have version X in it's system variables. The version in CloudKit will be changed to Y by this save operation. If user B tries to save the same record, then CloudKit will give an error because version X from the save is not the same as Y in the latest version. You can then react on that situation depending on what you want (re read and update or cancel) It's not that hard to create a unit test for that. It will look something like: |
but when the record is not exist before two users checking, not any version for no exist recored. In normal DB system, the index mechanism ensure that the same record could not be insert 2 times by index field. In some server system, a lock mechanism is provided. lock object, do operation with object, then unlock it. This mechanism ensure only a instance/user to do with the object. Does Cloudkit provide the similar mechanisms? Batch operation? Or Insert a record whatever the record existence, it will automatic insert and return new record or just return a existence record that just like your saving function (save or update). |
That's why you need a unique specific RecordId for the record. If person 1 saves that record, the 2nd can not save the same ID. He will get an error indicating that it already exists and needs to do a read and update. So you could say that the RecordId works like the primary index. There is no option to lock a record. You need to use the version mechanism for that. CloudKit does have support for bach operations (for instance use SaveItems instead of SaveItem). The mechanism described above will always work. You need to handle a failed save and react the way you would like to. EVCloudKitDao stays as close to the CloudKit implementation as possible. It's only a collection of convenience functions. As a layer on top of that EVCloudData has the .connect which joins the query and subscription functionality in one. |
Q1:How to assign RecordId in saveItem function? We can assign RecordId ourself for Cloudkit? Q2:Does code look like following?
Q4: If it's worked, existence checking is not necessary, we just save it with the unique recordid, new if success, exist if failed with specific error. right? Q5: the same situation for new/update a record? |
You could test it with code like this:
You will see this in the output:
So in the errorHandler of that 2nd save you could do a .getItem, change data and .save |
Existence must be checked before insert a record into table. but these are 2 operations(check&insert), when multiple users do this in the same time, it will cause issue of inserting 2 same records.
How to handle this?
UserA: |----> check ----> not existence ----> insert ----> insert succ
UserB: |--------> check ----> not existence ----> insert ----> insert succ
So 2 same records will be inserted into table.
The text was updated successfully, but these errors were encountered: