Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Layer 1 of MMS5 handles the versioning of ‘models’ on an abstracted layer above the triplestore quadstore by emulating a git version control paradigm. Under the hood, Layer 1 must orchestrate the atomic insertion and deletion of triples to various named graphs on a single triplestorequadstore.

The SPARQL 1.1 Update specification guarantees that multiple mutation queries submitted together will succeed or fail as an atomic unit (see Transaction Isolation Levels in Neptune as an example), meaning that a single HTTP POST request to the triplestore quadstore can affect multiple sequential changes as a single transaction. However, this feature alone does not solve all potential concurrency issues in the context of version control at the ‘model’ level when multiple clients must communicate with a single gateway sitting behind a RESTful web service interface.

These issues arise when requests to modify the same version of a model are made concurrently. The trivial technique for handling such circumstances would be to create a separate branch in the commit history for each request, essentially declaring a merge conflict anytime more than one request to modify the same resource is processed. The problem with this approach however would be the ever-growing number of branches, and the frequent need for human intervention to resolve such merge conflicts. Simply put, the branch-on-concurrent-write technique does not scale.

Optimistic Concurrency Control

A trivial solution for handling competing transactions is to allow the client to use preconditions when submitting SPARQL Updates with HTTP conditional requests. Essentially, an application can require that no other modifications have been made to some resource in order for their update to take effect. MMS5 facilitates conditional requests using ETags that it generates based on the modifications made to database objects and model commits.

For example, say an application creates a new branch develop:

Code Block
languagetext
PUT /orgs/openmbee/repos/demo/branches/develop

<> mms:ref <./main> .

MMS5 will respond with something like:

Code Block
HTTP/* 200
ETag: d9a333f7-18da-4009-8e96-7170417ece14

prefix mms: <https://mms.openmbee.org/rdf/ontology/>
...

Now the application can perform the first commit to this new branch by guaranteeing that no other clients/applications have mutated the branch since it was created by using the returned ETag in an If-Match header to form a conditional request:

Code Block
POST /orgs/openmbee/repos/demo/branches/develop/update
If-Match: d9a333f7-18da-4009-8e96-7170417ece14

insert data { ... }

If some other client or application has modified the branch, MMS5 will abort the update and respond with an HTTP 412 Precondition Failed code.

Intent

Returning to what causes the issue in the first place, clients cannot be expected to always have the most up-to-date knowledge about the state of the model they are attempting to mutate. However, concurrent requests do not necessarily need to cause merge conflicts. Instead, what is needed is an approach that allows for more flexibility, such that the use of stale knowledge when attempting to update a model does not automatically trigger a merge conflict.

...