Keith writes:

I do not personally see the benefit of moving the repeatable read guarantee to 
the BEGIN point rather than the first database read after the BEGIN because 
only fully committed transactions will be visible anyway -- …

Improved modularity would be facilitated by making it possible to actually 
begin a transaction immediately rather than having it be deferred until the 
associated DB access occurs.  Granted, when the sequence of events (BEGIN …, 
SELECT …, … TRANSACTION)  is viewed as a whole, deferring the guarantee makes 
only a slight difference to the work that must (or should) be done by the 
application.  But the deferral changes where checking must be done for actually 
obtaining the guarantee.  Presently, that checking has to be done in the code 
which makes the queries (or updates, inserts, etc.)  And that checking, which 
is needed on the first access statement only, is probably done with different 
requirements for handling the contention error than pertain to following 
statements.

Pseudo-code examples may clarify my point.

Now:
  Begin transaction;
  if ( failed( do first access ) ) {
    Handle contention error or more unusual errors;
    Rollback transaction;
  }
  else {
    if ( failed ( do subsequent accesses ) ) {
      Handle the rare and arcane access errors;
      Rollback transaction;
    }
    else {
      Commit transaction;
    }
  }

With guarantee moved up to BEGIN:
  If ( failed( begin transaction ) ) {
    Handle contention error;
  }
  else {
    if ( failed ( do must-be-grouped accesses ) ) {
      Handle the rare and arcane access errors;
      Rollback transaction;
    }
    else {
      Commit transaction;
    }
  }

When using C++, C# or another language with object lifetime guarantees, I might 
wrap the contention checking, waiting, etc., into a Transaction class which 
bundled the transaction mechanics with (some of) the error handling a 
contention failure entails.  The client code would read something like:
  using (var t = new Transaction(dbConnection) ) {
    if ( failed ( do must-be-grouped accesses ) ) {
      Handle access errors
      // t does the rollback when it goes out of scope.
    }
    else {
      t.Commit();
    }
  }
This grouping of handling for different error categories is made much less 
convenient by the present deferral of acquiring the necessary lock(s).

Best regards,
-
Larry Brasfield
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to