Re: Core Data with ODBC databases?
Re: Core Data with ODBC databases?
- Subject: Re: Core Data with ODBC databases?
- From: Brad Gibbs <email@hidden>
- Date: Thu, 17 Oct 2013 14:05:26 -0400
You make some great points, Jens.
Yes, the scenario I’m considering is a Rails server, hosted on Heroku, backed by a Postgres database.
Regarding your point about Core Data not being atomic:
1. It sounds like a perfectly reasonable and valid argument, but, then, why would Apple release NSIncrementalStore at all? What purpose would it serve? Was it just a mistake on their part? Something they didn’t think through fully? I believe you used to be an Apple employee. I’ve known a couple Apple software engineers and they’re not dumb people, by any stretch. Was this just a complete oversight, or is there some other intended use for NSIS that actually makes sense?
2. To make this more concrete, one of the objects in the app I’m pondering is a Project. The Project has attributes and relationships to other objects, like Phases, Products, LaborEntries, etc. The Project will have an owner (the Project Manager) and there might be one or two others with write access to make changes to a Project.
If I’m being wildly optimistic, I may one day have 50 users who can all view some or all of the Project information, but only three of whom may edit it. Say one of the users with write access edits the Project by changing five of its attributes. Before the user is allowed to move to another view to edit a different object or view another Project, he is required to confirm that he wants the changes to be saved. If the save is confirmed, an NSManagedObjectContextDidSave notification fires. At that point, the userInfo dictionary contains a single object — the updated Project in the userInfo’s NSUpdatedObjects dictionary. That Project object is then serialized and POSTed to the server.
It’s possible that one of the other two users with write access could be making changes to one of those five fields at the same time. If this happens, whichever save operation happens last wins and this could produce some undesirable consequences if the person who posted the second commit entered incorrect information. BUT, unless both users confirm their changes at precisely the same moment, isn’t it more-or-less equivalent to two transactions where the last one in wins? In other words, if the app is written such that users are forced to commit changes frequently enough, doesn’t it at some point become a transaction?
Furthermore, with server-sent events (a la Rocket.io), if two users are editing the same project simultaneously and one commits his changes, the other will be notified of the changes immediately and will know if he is overwriting changes someone else made (seeing a record change while you’re looking at it could take some getting used to…).
I can definitely see how this lack of atomicity could cause serious problems if you’ve got 10,000 users with edit permissions and users can make several changes to several objects before committing, but, in this particular use case, maybe it isn’t a big enough issue to throw the baby out with the bathwater?
What better options should I look at, instead? My company is three employees strong at the moment and we’re never going to be on the same LAN. I’ve looked at CouchBase, but I’m not sure NoSQL is the right fit.
On Oct 17, 2013, at 12:49 PM, Jens Alfke <email@hidden> wrote:
>
> On Oct 17, 2013, at 8:19 AM, Brad Gibbs <email@hidden> wrote:
>
>> Core Data is still a local cache being used by a single user, but instead of persisting to the local disk, it’s persisting to the Postgres server.
>
> But not directly, right? You said there was a Rails app in the middle serving up a REST API.
>
>> As for two people making changes to a record simultaneously, it would be handled in the same way a Rails web app would handle it. Rails and Postgres have been designed for this use case.
>
> It’s been a while since I used Rails, but the typical way that a database-driven app manages this is using transactions. Begin transaction, update rows, end transaction. That makes all the updates atomic.
>
> But NSIncrementalStore doesn’t have a notion of a transaction, because CoreData doesn’t care about concurrency, because it’s not multi-user. So if your Core Data app makes a bunch of changes, they’re going to be sent to the store, which is going to send them off as individual PUT/POST/DELETE requests. These can’t be handled atomically by the server; they’re independent requests. So they can be interleaved with other updates being made by other clients, causing trouble. Or one of them might fail for some reason, but then there’s no way to back out to a consistent state; more trouble.
>
>> As for large data sets, that’s part of the beauty of the NSIncrementalStore approach. In its purest form, the full data set wouldn’t exist on any one user’s device. Instead, NSIncrementalStore would fetch the data requested by the user from the server, as needed, by firing faults. If NSIncrementalStore worked as advertised, there would be no need to persist the entire data set to a user’s device.
>
> I haven’t dug all the way into NSIncrementalStore yet. But the assumption you’re making is that you can take an architecture that works for a local single-user database, and transparently make it work over a worldwide network with lots of users just by [colorful metaphor ahead, not meant to be insulting!] snipping the wire labeled “SQLite” and soldering it to a wire labeled “Internet”. This is _exactly_ the kind of thing the “Fallacies Of Distributed Computing” article warns against … because those fallacies don’t apply to tightly-bound systems like CoreData+SQLite, and are often ignorable in LAN-based systems like the typical app-server+db-server setup in a data center. But on the Internet they will bite you.
>
> —Jens
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden