Access Controls

David Merrill dmerrill@lupercalia.net
Fri, 29 Dec 2000 14:28:33 -0500


On Fri, Dec 29, 2000 at 12:39:17PM -0600, linas@linas.org wrote:
> It's been rumoured that David Merrill said:
> > 
> > Do you mean to
> > set a "lock" (not a real DB lock though, or at least not necessarily a
> > real DB lock) when the user BEGINS to do an edit, so other users
> > cannot? Now THAT makes sense. :-)
> 
> Yes. I tend to speak metaphorically. 

And I tend to interpret literally. :-) My S.O. teases me all the time
for insisting on using correct terminology for things. Yes, I was one
of those "but the millenium doesn't start until 2001! folks. But
s'okay, we'll figure it out eventually.
 
> > > If you think about it as a transport mechanism, then Begin(), End()
> > > are the *only* times a message needs to be sent from client to server.
> > > After a session has been intiated, *none* of the other API calls should 
> > > generate traffic.  
> > 
> > Now you lost me. ???
> 
> Lets assume we are using onc-rpc (or corba or xml-rpc or soap).
> 
> ** GUI user uses mouse to highlight transaction for editing.
> ** xaccTransBeginEdit() sends rpc/iiop/xml message to server.
> ** GUI user types in payee, amount
> ** xaccTransSetDescription(), xaccTransSetAmount() are invoked
>    by gtk code.  But no rpc's are made; no network traffic.
> ** GUI user has finished,  clicks 'OK, commit'.
> ** xaccTransCommitEdit() is called.  It packs up all the changes
>    into one block, and ships that off to server via rpc. 
> ** Server does whatever it needs to do with that data (e.g. 
>    punches it into SQL).
> ** Server replies 'sucess' or 'failure'
> ** GUI pops  message 'thank you for entering that transaction.
>    please come again'.  

Okay. I got it now.

The concurrency issue is still unresolved. Let me take a stab at it.


Option 1, no concurrent edits allowed:

client 1 -> server "I want to edit record 1"
server -> client 1 "OK"

client 2 -> server "I want to edit record 1"
server -> client 2 "NO"

Only one user can edit at a time. Easy to implement; can be
frustrating to the user.


Option 2, concurrency allowed, changes are merged:

In order to merge changes, the db has to know the state of the data
the user was editing, as well as the new state of the data. But a
mechanism for retaining a complete audit trail is already in place for
other reasons, so why not use it for this? So if we take the cvs
approach, it could work like this:

client -> server "Here is an update to record 1"

server checks to see if record still exists in transaction table

IF YES	move original record to audit table

	save new record in transaction table

	server -> client "OK"

IF NO	has client changed the same fields as the other client?

	IF YES	server -> client "FAILURE"

	IF NO	move other client's edits to audit table

		save new record in transaction table

		server -> client "OK"

The only failure happens when two or more users have edited the same
field concurrently. There's really nothing we can do about that but
fail gracefully and let them re-edit if they wish.

Note that this approach does not requre the client to pre-authorize
its edits from the server, and so results in even fewer rpc calls. In
real world use, collisions between users are few and far between.

Regardless of which concurrency mechanism is used, we still have to
provide for data changed by others but not yet updated at the client's
machine:

client -> server
	"I want to edit record 1"
server -> client
	"Record has changed since you got it. Please update."
client -> server
	"Please give me new data for record 1 (or records 1-100)"
server -> client
	"Okay, here it is..."

Or the (possibly) more efficient:

client -> server
	"I want to edit record 1"
server -> client
	"It's changed. Here is the new data..."

I say possibly because the client may prefer to retrieve a complete
update instead of the single record (or actually structure, not just a
record). The first approach allows to the client the flexibility to
determine what data it gets, and then retrieves that data using the
normal mechanism.

And because the cvs approach doesn't actually *require* the client to
check out the record, it is optional whether or not it notifies the
engine of its intent. Of course, it is highly recommended. :-)

The difference is that the server doesn't really do anything with the
information. It just lets the client know if they are editing old
data. It doesn't check out the record or lock it.

-- 
Dr. David C. Merrill                     http://www.lupercalia.net
Linux Documentation Project                dmerrill@lupercalia.net
Collection Editor & Coordinator            http://www.linuxdoc.org
                                       Finger me for my public key

Do you know the old language?
I do not know the old language.
Do you kow the language of the old belief?
		-- Robert Duncan