Optimistic concurrency tests

When the SqlDataStore writes updates into the database it appends a WHERE clause containing the old values for all columns. This is a standard approach to avoid a lost update scenario. (If another client has changed some data the update fails because the where clause doesn't match, and that is the right thing because otherwise we would overwrite the change without ever having seen it.) Using all columns is only one approach, though.

Typically, one would exclude BLOBs from the WHERE clause or, taking domain knowledge into account, further restrict the set of columns. This feature, to specify a subset of the columns for the optimistic concurrency test, is something that should be added to Neo at some point.

SQL Server, and I'm sure other databases as well, also provide a means for yet another approach: When fetching the data from the database one could also fetch the rows TIMESTAMP column. (This has nothing to do with time, think of it as a row version.) When updating the data, the SqlStore could simply try to match the timestamp.

Labels

 
(None)
  1. Sep 14, 2004

    Ingo Lundberg says:

    May I also suggest looking into using a "wrapable" counter as version marker. Wh...

    May I also suggest looking into using a "wrapable" counter as version marker. When you use timestamp, there's no other way for the object instance to get the current value (of the timestamp) other than reading the correlating row from the database. You're forced to do an extra db access.

    When you use the kind of counter I'm talking about, you know that if you don't get an optimistic concurrency violation at "store" of the object, the counter will be:
    counter = counter == short.MaxValue ? short.MinValue : counter + 1;
    The counter and pkey is of course the only fields in the where clause to the update. The counter increment is coded in the framework (nothing that a db can give you for free).

    All you need to do now (after store) to be able to get the correct version mark in the object is to increment to "in memory" counter the same way as the counter in the database.

    Hmm, do I make myself understandable here?