RE: [PHP] Multiple Access Question

2010-07-08 Thread Tommy Pham
 -Original Message-
 From: Robert Cummings [mailto:rob...@interjinn.com]
 Sent: Wednesday, July 07, 2010 10:28 PM
 To: Paul M Foster
 Cc: php-general@lists.php.net
 Subject: Re: [PHP] Multiple Access Question
 
 Paul M Foster wrote:
  On Wed, Jul 07, 2010 at 11:28:56PM -0400, Robert Cummings wrote:
 
  Paul M Foster wrote:
 
  snip
 
  @Paul,
 
  The OPs question is about concurrency on the record itself. How to
  avoid two users accessing the same record and potentially damaging
  each others changes
 
  My approach is the same as Rob's. Flag it locked and let the second
  user gets a read only copy
  I can't think of a way to do this using MySQL or PostgreSQL. And one
  of the biggest issues with the solution you suggest is the user who
  opens a record for writing and then goes out for coffee. Everyone's
  locked out of the record (for writes) until they come back and finish.
 
  Okay, to solve that, we start a timer. But when the locker's time is
  up, how do we let the locker know they're not allowed to store
  whatever edits they've made? And how do we fix it so that those
  locked out are now unlocked? Plus, they're probably in a queue, so
  we really only let one of them know that they can now make edits.
 
  Since this is a PHP list, I assume we're talking about a web interface.
  So how do we do all this back end jockeying? Javascript is about the
  only way. But every time you fire off one of these javascript
  dealies, it has to be on its own timer so that it can let the user
  know that the original locker is gone and now the golden ticket is
  yours. It essentially has to sleep and ping, sleep and ping.
  Actually, it's more like a spinlock. But a spinlock would eat CPU
  for every user, if it was running on the server. So it would have to
  be running on the client, and ping the server every once in a while.
 
  Then you'd have to figure out some kind of messaging infrastrucure
  for the DBMS, so that it would quickly answer pings without tying
  up a lot of CPU cycles. It would have to be something outside the
  normal query infrastructure.
 
  When you actually get into this, it's an incredibly complex
  solution. I vote instead for allowing edits to be queued, log
  changes to the database. If there is a true contention problem, you
  can look at the journal and see who made what edits in what order
  and resolve the situation.
 
  The best analogy I can think of is when using a DVCS like git, and
  trying to merge changes where two people have edited the same area
  of a file. Ultimately, git throws up its hands and asks a human to
  resolve the situation.
 
  Bottom line: I've heard about concurrency problems since I started
  using databases, and I've never heard of a foolproof solution for
  them that wasn't incredibly complex. And I don't think I've ever
  seen a solution in actual practice.
 
  If I'm wrong, someone show me where it's been viably solved and how.
  I think you're overthinking the issue. The timer handles the issue of
  holding onto a lock for too long.
 
  That's why I suggested it.
 
  As for a write queue... don't bother.
  If a user finds that another user has a lock then tell them when it
  expires. They can come back and try for the lock on their own. You
  can set up AJAX polling to see if the lock has been removed and
  indicate this to the user (if they've bothered to wait on the page)
  but this is optional.
 
  That's why I suggested it.
 
  Yes, we could just tell users come back later if they wanted to edit
  a locked page. I was just imagining a 100% complete
  wipe-your-butt-for-you solution.
 
  Queuing edits is not a good solution.
 
  And yet, it appears to adequate for the DBMSes I'm familiar with.
 
  Imagine document X:
 
  UserA requests X
  UserB requests X
  UserC requests X
  UserD requests X
 
  UserA modifies X and saves X.1
  UserB modifies X and saves X.2
  UserC modifies X and saves X.3
  UserD modifies X and saves X.4
 
  In this scenario all the work done by UserA, UserB, and UserC is
  clobbered by the submission by UserD. This can be resolved via
  merging such as used by versioning systems,
 
  ... if automatic merging can be done in a particular case. But there's
  a non-zero probability that a merge will require human intervention.
  Yes of course, without version/merging or some type of write-locks,
  there is potential contention.
 
  but this makes less sense in a high
  traffic collaborative content system such as a wiki. In the lock
  scenario we have the following:
 
  UserA requests X
  UserA modifies X and saves X.1
 
  UserB requests X.1
  UserB modifies X.1 and saves X.2
 
  UserC requests X.2
  UserC modifies X.2 and saves X.3
 
  UserD requests X.3
  UserD modifies X.3 and saves X.4
 
  ... assuming UserB waits until UserA stores his edits, UserC waits
  until UserB stores his edits, etc. The above assumes locking, and
  probably versioning

Re: [PHP] Multiple Access Question

2010-07-08 Thread Richard Quadling
On 7 July 2010 17:59, tedd t...@sperling.com wrote:
 Hi gang:

 I have *my way* of handling this problem, but I would like to hear how you
 guys do it.

 Here's the problem -- let's say you have a database containing names and
 addresses and you want approved users to be able to access the data. As
 such, a user must login before accessing an editing script that would allow
 them to review and edit the data -- nothing complicated about that.

 However, let's say you have more than one user accessing the editing script
 at the same time and you want to make sure that any changes made to the
 database are done in the most efficient manner possible.

 For example, if two users access the database at the same time and are
 editing different records, then there's no real problem. When each user
 finishes editing they simply click submit and their changes are recorded in
 the database. However, if two (or more) users want to access the same
 record, then how do you handle that?

 Cheers,

 tedd

I've developed many multi-user applications (specialising in
Accounting and EPOS systems).

Primarily for DOS and Windows and using SQL Server and D-ISAM data
storage systems.

In all instances, multi-user locking is handled through the use of a
semaphore at the row level. We did look at semaphore locking at the
field level.

For DOS and Windows, the necessity for handling timeouts was reduced
by the fact that if the user was logged in to the app, then the lock
stays - and much to the annoyance of all other users. A simple process
to allow locks for a user to be dropped was required to handle the
instances were the user powered off/crashed/forgot password over lunch
situations. In real terms, the number of collisions was very low. Few
users would actually be entering data into the same record at the same
time. In the vast majority, all the users are in the same room or, at
least, the same building/office.

When I started the web versions of these apps, the semaphore locking
was still required, but was extended to include a timeout based upon
the session timeout.

We did realize that by using web based technology, some of our clients
were looking to allow their users to work from home. So informing the
user that a row was locked, how long it was locked for and who else
wanted it was well worth while.

So we introduced a new structure of lock requests. This was a simple
table containing the id of the current semaphore (all our semaphores
are in a single table), the user id of the person wanting the row and
when they requested the lock.

A user who is placed in the lock requests loop could reject their
request (i.e. come back later sort of thing).

The lock requests would be displayed to the lock holder so that they
could essentially get the message to hurry up - in the office someone
would call out Is anyone in so-and-so? and then someone would reply
Oh yes! Sorry, just coming out now. sort of thing. This process
worked fine. The clients knew that only 1 edit could take place at a
time.

With a distributed work force, the on screen visualisation worked
well. A small little drop down in the corner of the app. Nice and
easy.

As the server is more or less constantly being told of the presence of
a user (say once every 30 seconds), the server can easily detect a
dropped user and therefore undo the lock.

The user next in the lock requests table would automatically get the
lock and be informed via the ping that they had control of the row
(disabled inputs would become enabled, etc.). Their entry in the lock
requests table would be deleted and anyone else would see that they
have moved up the queue.

I hope this is of some use to you. Semaphores worked really well for
our apps. The transition from DOS/Windows to the web wasn't as easy as
it could have been - primarily due to the statelessness of the
requests. We did manage to do it without the need for any additional
monitors running on the server. All based upon simply tracking the
datetime of the lock requests, the table lock timeout and the session
timeout.

In all instances, if a lock has to be cleared due to a timeout, all
the unwritten data (we used AJAX to send edits to the server for
holding) would be held, but the lock removed and the user forced to
login again.

On the old system, a lock could persist and cause everyone to wait. On
the web, a lock could NOT persist and the user creating the lock would
suffer the punishment of having to relogin, retrieve their edits
(which may now be stale) and to try again.


Whatever technique you use, I would recommend getting it as close to
the database as possible. The use of stored procedures, for us, was
essential. Lock evaluation and enforcement was all done within the SQL
server - all apps have to use the stored procedures and this makes the
apps a lot simpler. And allows any app to use the same locking
techniques irrespective of the language the developer wanted to use -
our apps allowed for third party additions to the 

Re: [PHP] Multiple Access Question

2010-07-08 Thread tedd

At 11:48 AM +0100 7/8/10, Richard Quadling wrote:

On 7 July 2010 17:59, tedd t...@sperling.com wrote:

 Hi gang:

 I have *my way* of handling this problem, but I would like to hear how you

  guys do it.



-snip-

I hope this is of some sense to you. It certainly is an interesting topic.

Richard.


Richard:

Yes, it was very informative and useful -- it gave me an idea to try out.

Thanks very much for your most extensive answer.

Cheers,

tedd
--
---
http://sperling.com  http://ancientstones.com  http://earthstones.com

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Multiple Access Question

2010-07-07 Thread Robert Cummings

tedd wrote:

Hi gang:

I have *my way* of handling this problem, but I would like to hear 
how you guys do it.


Here's the problem -- let's say you have a database containing names 
and addresses and you want approved users to be able to access the 
data. As such, a user must login before accessing an editing script 
that would allow them to review and edit the data -- nothing 
complicated about that.


However, let's say you have more than one user accessing the editing 
script at the same time and you want to make sure that any changes 
made to the database are done in the most efficient manner possible.


For example, if two users access the database at the same time and 
are editing different records, then there's no real problem. When 
each user finishes editing they simply click submit and their changes 
are recorded in the database. However, if two (or more) users want to 
access the same record, then how do you handle that?


I would provide read access whatever the case. For write access I would 
place a lock on the data for the first user to make the edit request. 
The lock would have an expiry time, and the user in possession of the 
lock could reset it if they need more time. Other users would be alerted 
that another user is currently editing the data and that the lock will 
expire in X minutes. If the user completes their edit before the timer 
expires, then the timer will be automatically cleared upon commit of the 
changes. Optionally, the user who doesn't get the lock could be alerted 
to what user currently has the lock. Additionally, if we get complicated 
we could allow a higher authority to steal the lock and alert the user 
making edits.


Cheers,
Rob.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Multiple Access Question

2010-07-07 Thread Paul M Foster
On Wed, Jul 07, 2010 at 12:59:30PM -0400, tedd wrote:

 Hi gang:

 I have *my way* of handling this problem, but I would like to hear
 how you guys do it.

 Here's the problem -- let's say you have a database containing names
 and addresses and you want approved users to be able to access the
 data. As such, a user must login before accessing an editing script
 that would allow them to review and edit the data -- nothing
 complicated about that.

 However, let's say you have more than one user accessing the editing
 script at the same time and you want to make sure that any changes
 made to the database are done in the most efficient manner possible.

 For example, if two users access the database at the same time and
 are editing different records, then there's no real problem. When
 each user finishes editing they simply click submit and their changes
 are recorded in the database. However, if two (or more) users want to
 access the same record, then how do you handle that?

Use a DBMS? I'm sorry if that seems flippant, but a DBMS handles this by
queuing the requests, which is one of the advantages of a client-server
DBMS.

So maybe I don't understand your question.

Paul

-- 
Paul M. Foster

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Multiple Access Question

2010-07-07 Thread Bastien Koert
On Wed, Jul 7, 2010 at 8:47 PM, Paul M Foster pa...@quillandmouse.com wrote:
 On Wed, Jul 07, 2010 at 12:59:30PM -0400, tedd wrote:

 Hi gang:

 I have *my way* of handling this problem, but I would like to hear
 how you guys do it.

 Here's the problem -- let's say you have a database containing names
 and addresses and you want approved users to be able to access the
 data. As such, a user must login before accessing an editing script
 that would allow them to review and edit the data -- nothing
 complicated about that.

 However, let's say you have more than one user accessing the editing
 script at the same time and you want to make sure that any changes
 made to the database are done in the most efficient manner possible.

 For example, if two users access the database at the same time and
 are editing different records, then there's no real problem. When
 each user finishes editing they simply click submit and their changes
 are recorded in the database. However, if two (or more) users want to
 access the same record, then how do you handle that?

 Use a DBMS? I'm sorry if that seems flippant, but a DBMS handles this by
 queuing the requests, which is one of the advantages of a client-server
 DBMS.

 So maybe I don't understand your question.

 Paul

 --
 Paul M. Foster

 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php



@Paul,

The OPs question is about concurrency on the record itself. How to
avoid two users accessing the same record and potentially damaging
each others changes

My approach is the same as Rob's. Flag it locked and let the second
user gets a read only copy


-- 

Bastien

Cat, the other other white meat

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Multiple Access Question

2010-07-07 Thread Paul M Foster
On Wed, Jul 07, 2010 at 10:01:05PM -0400, Bastien Koert wrote:

 On Wed, Jul 7, 2010 at 8:47 PM, Paul M Foster pa...@quillandmouse.com
 wrote:
  On Wed, Jul 07, 2010 at 12:59:30PM -0400, tedd wrote:
 
  Hi gang:
 
  I have *my way* of handling this problem, but I would like to hear
  how you guys do it.
 
  Here's the problem -- let's say you have a database containing names
  and addresses and you want approved users to be able to access the
  data. As such, a user must login before accessing an editing script
  that would allow them to review and edit the data -- nothing
  complicated about that.
 
  However, let's say you have more than one user accessing the editing
  script at the same time and you want to make sure that any changes
  made to the database are done in the most efficient manner possible.
 
  For example, if two users access the database at the same time and
  are editing different records, then there's no real problem. When
  each user finishes editing they simply click submit and their changes
  are recorded in the database. However, if two (or more) users want to
  access the same record, then how do you handle that?
 
  Use a DBMS? I'm sorry if that seems flippant, but a DBMS handles this by
  queuing the requests, which is one of the advantages of a client-server
  DBMS.
 
  So maybe I don't understand your question.
 
  Paul
 
  --
  Paul M. Foster
 
  --
  PHP General Mailing List (http://www.php.net/)
  To unsubscribe, visit: http://www.php.net/unsub.php
 
 
 
 @Paul,
 
 The OPs question is about concurrency on the record itself. How to
 avoid two users accessing the same record and potentially damaging
 each others changes
 
 My approach is the same as Rob's. Flag it locked and let the second
 user gets a read only copy

I can't think of a way to do this using MySQL or PostgreSQL. And one of
the biggest issues with the solution you suggest is the user who opens a
record for writing and then goes out for coffee. Everyone's locked out
of the record (for writes) until they come back and finish.

Okay, to solve that, we start a timer. But when the locker's time is up,
how do we let the locker know they're not allowed to store whatever
edits they've made? And how do we fix it so that those locked out are
now unlocked? Plus, they're probably in a queue, so we really only let
one of them know that they can now make edits.

Since this is a PHP list, I assume we're talking about a web interface.
So how do we do all this back end jockeying? Javascript is about the
only way. But every time you fire off one of these javascript dealies,
it has to be on its own timer so that it can let the user know that the
original locker is gone and now the golden ticket is yours. It
essentially has to sleep and ping, sleep and ping. Actually, it's more
like a spinlock. But a spinlock would eat CPU for every user, if it was
running on the server. So it would have to be running on the client, and
ping the server every once in a while.

Then you'd have to figure out some kind of messaging infrastrucure for
the DBMS, so that it would quickly answer pings without tying up a lot
of CPU cycles. It would have to be something outside the normal query
infrastructure.

When you actually get into this, it's an incredibly complex solution. I
vote instead for allowing edits to be queued, log changes to the
database. If there is a true contention problem, you can look at the
journal and see who made what edits in what order and resolve the
situation.

The best analogy I can think of is when using a DVCS like git, and
trying to merge changes where two people have edited the same area of a
file. Ultimately, git throws up its hands and asks a human to resolve
the situation.

Bottom line: I've heard about concurrency problems since I started using
databases, and I've never heard of a foolproof solution for them that
wasn't incredibly complex. And I don't think I've ever seen a solution
in actual practice.

If I'm wrong, someone show me where it's been viably solved and how.

Paul

-- 
Paul M. Foster

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Multiple Access Question

2010-07-07 Thread Robert Cummings

Paul M Foster wrote:

On Wed, Jul 07, 2010 at 10:01:05PM -0400, Bastien Koert wrote:


On Wed, Jul 7, 2010 at 8:47 PM, Paul M Foster pa...@quillandmouse.com
wrote:

On Wed, Jul 07, 2010 at 12:59:30PM -0400, tedd wrote:


Hi gang:

I have *my way* of handling this problem, but I would like to hear
how you guys do it.

Here's the problem -- let's say you have a database containing names
and addresses and you want approved users to be able to access the
data. As such, a user must login before accessing an editing script
that would allow them to review and edit the data -- nothing
complicated about that.

However, let's say you have more than one user accessing the editing
script at the same time and you want to make sure that any changes
made to the database are done in the most efficient manner possible.

For example, if two users access the database at the same time and
are editing different records, then there's no real problem. When
each user finishes editing they simply click submit and their changes
are recorded in the database. However, if two (or more) users want to
access the same record, then how do you handle that?

Use a DBMS? I'm sorry if that seems flippant, but a DBMS handles this by
queuing the requests, which is one of the advantages of a client-server
DBMS.

So maybe I don't understand your question.

Paul

--
Paul M. Foster

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



@Paul,

The OPs question is about concurrency on the record itself. How to
avoid two users accessing the same record and potentially damaging
each others changes

My approach is the same as Rob's. Flag it locked and let the second
user gets a read only copy


I can't think of a way to do this using MySQL or PostgreSQL. And one of
the biggest issues with the solution you suggest is the user who opens a
record for writing and then goes out for coffee. Everyone's locked out
of the record (for writes) until they come back and finish.

Okay, to solve that, we start a timer. But when the locker's time is up,
how do we let the locker know they're not allowed to store whatever
edits they've made? And how do we fix it so that those locked out are
now unlocked? Plus, they're probably in a queue, so we really only let
one of them know that they can now make edits.

Since this is a PHP list, I assume we're talking about a web interface.
So how do we do all this back end jockeying? Javascript is about the
only way. But every time you fire off one of these javascript dealies,
it has to be on its own timer so that it can let the user know that the
original locker is gone and now the golden ticket is yours. It
essentially has to sleep and ping, sleep and ping. Actually, it's more
like a spinlock. But a spinlock would eat CPU for every user, if it was
running on the server. So it would have to be running on the client, and
ping the server every once in a while.

Then you'd have to figure out some kind of messaging infrastrucure for
the DBMS, so that it would quickly answer pings without tying up a lot
of CPU cycles. It would have to be something outside the normal query
infrastructure.

When you actually get into this, it's an incredibly complex solution. I
vote instead for allowing edits to be queued, log changes to the
database. If there is a true contention problem, you can look at the
journal and see who made what edits in what order and resolve the
situation.

The best analogy I can think of is when using a DVCS like git, and
trying to merge changes where two people have edited the same area of a
file. Ultimately, git throws up its hands and asks a human to resolve
the situation.

Bottom line: I've heard about concurrency problems since I started using
databases, and I've never heard of a foolproof solution for them that
wasn't incredibly complex. And I don't think I've ever seen a solution
in actual practice.

If I'm wrong, someone show me where it's been viably solved and how.


I think you're overthinking the issue. The timer handles the issue of 
holding onto a lock for too long. As for a write queue... don't bother. 
If a user finds that another user has a lock then tell them when it 
expires. They can come back and try for the lock on their own. You can 
set up AJAX polling to see if the lock has been removed and indicate 
this to the user (if they've bothered to wait on the page) but this is 
optional. Queuing edits is not a good solution. Imagine document X:


UserA requests X
UserB requests X
UserC requests X
UserD requests X

UserA modifies X and saves X.1
UserB modifies X and saves X.2
UserC modifies X and saves X.3
UserD modifies X and saves X.4

In this scenario all the work done by UserA, UserB, and UserC is 
clobbered by the submission by UserD. This can be resolved via merging 
such as used by versioning systems, but this makes less sense in a high 
traffic collaborative content system such as a wiki. In the lock 
scenario we 

Re: [PHP] Multiple Access Question

2010-07-07 Thread Paul M Foster
On Wed, Jul 07, 2010 at 11:28:56PM -0400, Robert Cummings wrote:

 Paul M Foster wrote:

snip

 @Paul,

 The OPs question is about concurrency on the record itself. How to
 avoid two users accessing the same record and potentially damaging
 each others changes

 My approach is the same as Rob's. Flag it locked and let the second
 user gets a read only copy

 I can't think of a way to do this using MySQL or PostgreSQL. And one of
 the biggest issues with the solution you suggest is the user who opens a
 record for writing and then goes out for coffee. Everyone's locked out
 of the record (for writes) until they come back and finish.

 Okay, to solve that, we start a timer. But when the locker's time is up,
 how do we let the locker know they're not allowed to store whatever
 edits they've made? And how do we fix it so that those locked out are
 now unlocked? Plus, they're probably in a queue, so we really only let
 one of them know that they can now make edits.

 Since this is a PHP list, I assume we're talking about a web interface.
 So how do we do all this back end jockeying? Javascript is about the
 only way. But every time you fire off one of these javascript dealies,
 it has to be on its own timer so that it can let the user know that the
 original locker is gone and now the golden ticket is yours. It
 essentially has to sleep and ping, sleep and ping. Actually, it's more
 like a spinlock. But a spinlock would eat CPU for every user, if it was
 running on the server. So it would have to be running on the client, and
 ping the server every once in a while.

 Then you'd have to figure out some kind of messaging infrastrucure for
 the DBMS, so that it would quickly answer pings without tying up a lot
 of CPU cycles. It would have to be something outside the normal query
 infrastructure.

 When you actually get into this, it's an incredibly complex solution. I
 vote instead for allowing edits to be queued, log changes to the
 database. If there is a true contention problem, you can look at the
 journal and see who made what edits in what order and resolve the
 situation.

 The best analogy I can think of is when using a DVCS like git, and
 trying to merge changes where two people have edited the same area of a
 file. Ultimately, git throws up its hands and asks a human to resolve
 the situation.

 Bottom line: I've heard about concurrency problems since I started using
 databases, and I've never heard of a foolproof solution for them that
 wasn't incredibly complex. And I don't think I've ever seen a solution
 in actual practice.

 If I'm wrong, someone show me where it's been viably solved and how.

 I think you're overthinking the issue. The timer handles the issue of
 holding onto a lock for too long. 

That's why I suggested it.

 As for a write queue... don't bother.
 If a user finds that another user has a lock then tell them when it
 expires. They can come back and try for the lock on their own. You can
 set up AJAX polling to see if the lock has been removed and indicate
 this to the user (if they've bothered to wait on the page) but this is
 optional. 

That's why I suggested it.

Yes, we could just tell users come back later if they wanted to edit a
locked page. I was just imagining a 100% complete wipe-your-butt-for-you
solution.

 Queuing edits is not a good solution. 

And yet, it appears to adequate for the DBMSes I'm familiar with.

 Imagine document X:

 UserA requests X
 UserB requests X
 UserC requests X
 UserD requests X

 UserA modifies X and saves X.1
 UserB modifies X and saves X.2
 UserC modifies X and saves X.3
 UserD modifies X and saves X.4

 In this scenario all the work done by UserA, UserB, and UserC is
 clobbered by the submission by UserD. This can be resolved via merging
 such as used by versioning systems, 

... if automatic merging can be done in a particular case. But there's a
non-zero probability that a merge will require human intervention. Yes
of course, without version/merging or some type of write-locks, there is
potential contention.

 but this makes less sense in a high
 traffic collaborative content system such as a wiki. In the lock
 scenario we have the following:

 UserA requests X
 UserA modifies X and saves X.1

 UserB requests X.1
 UserB modifies X.1 and saves X.2

 UserC requests X.2
 UserC modifies X.2 and saves X.3

 UserD requests X.3
 UserD modifies X.3 and saves X.4

... assuming UserB waits until UserA stores his edits, UserC waits until
UserB stores his edits, etc. The above assumes locking, and probably
versioning and merging.

But a wiki is not a DBMS. And perhaps the OP was talking about a wiki.
In which case, all this may be moot. I just checked, and Wikipedia does
not lock pages under edit. They do versioning, but their locking is on
the honor system. For a discourteous user, this would allow contention.
I don't know if other wikis perform locking. I doubt it, but I could be

Re: [PHP] Multiple Access Question

2010-07-07 Thread Robert Cummings

Paul M Foster wrote:

On Wed, Jul 07, 2010 at 11:28:56PM -0400, Robert Cummings wrote:


Paul M Foster wrote:


snip


@Paul,

The OPs question is about concurrency on the record itself. How to
avoid two users accessing the same record and potentially damaging
each others changes

My approach is the same as Rob's. Flag it locked and let the second
user gets a read only copy

I can't think of a way to do this using MySQL or PostgreSQL. And one of
the biggest issues with the solution you suggest is the user who opens a
record for writing and then goes out for coffee. Everyone's locked out
of the record (for writes) until they come back and finish.

Okay, to solve that, we start a timer. But when the locker's time is up,
how do we let the locker know they're not allowed to store whatever
edits they've made? And how do we fix it so that those locked out are
now unlocked? Plus, they're probably in a queue, so we really only let
one of them know that they can now make edits.

Since this is a PHP list, I assume we're talking about a web interface.
So how do we do all this back end jockeying? Javascript is about the
only way. But every time you fire off one of these javascript dealies,
it has to be on its own timer so that it can let the user know that the
original locker is gone and now the golden ticket is yours. It
essentially has to sleep and ping, sleep and ping. Actually, it's more
like a spinlock. But a spinlock would eat CPU for every user, if it was
running on the server. So it would have to be running on the client, and
ping the server every once in a while.

Then you'd have to figure out some kind of messaging infrastrucure for
the DBMS, so that it would quickly answer pings without tying up a lot
of CPU cycles. It would have to be something outside the normal query
infrastructure.

When you actually get into this, it's an incredibly complex solution. I
vote instead for allowing edits to be queued, log changes to the
database. If there is a true contention problem, you can look at the
journal and see who made what edits in what order and resolve the
situation.

The best analogy I can think of is when using a DVCS like git, and
trying to merge changes where two people have edited the same area of a
file. Ultimately, git throws up its hands and asks a human to resolve
the situation.

Bottom line: I've heard about concurrency problems since I started using
databases, and I've never heard of a foolproof solution for them that
wasn't incredibly complex. And I don't think I've ever seen a solution
in actual practice.

If I'm wrong, someone show me where it's been viably solved and how.

I think you're overthinking the issue. The timer handles the issue of
holding onto a lock for too long. 


That's why I suggested it.


As for a write queue... don't bother.
If a user finds that another user has a lock then tell them when it
expires. They can come back and try for the lock on their own. You can
set up AJAX polling to see if the lock has been removed and indicate
this to the user (if they've bothered to wait on the page) but this is
optional. 


That's why I suggested it.

Yes, we could just tell users come back later if they wanted to edit a
locked page. I was just imagining a 100% complete wipe-your-butt-for-you
solution.

Queuing edits is not a good solution. 


And yet, it appears to adequate for the DBMSes I'm familiar with.


Imagine document X:

UserA requests X
UserB requests X
UserC requests X
UserD requests X

UserA modifies X and saves X.1
UserB modifies X and saves X.2
UserC modifies X and saves X.3
UserD modifies X and saves X.4

In this scenario all the work done by UserA, UserB, and UserC is
clobbered by the submission by UserD. This can be resolved via merging
such as used by versioning systems, 


... if automatic merging can be done in a particular case. But there's a
non-zero probability that a merge will require human intervention. Yes
of course, without version/merging or some type of write-locks, there is
potential contention.


but this makes less sense in a high
traffic collaborative content system such as a wiki. In the lock
scenario we have the following:

UserA requests X
UserA modifies X and saves X.1

UserB requests X.1
UserB modifies X.1 and saves X.2

UserC requests X.2
UserC modifies X.2 and saves X.3

UserD requests X.3
UserD modifies X.3 and saves X.4


... assuming UserB waits until UserA stores his edits, UserC waits until
UserB stores his edits, etc. The above assumes locking, and probably
versioning and merging.


No, not at all. Each user can only edit the version last saved. It only 
assumes locking.



But a wiki is not a DBMS. And perhaps the OP was talking about a wiki.
In which case, all this may be moot. I just checked, and Wikipedia does
not lock pages under edit. They do versioning, but their locking is on
the honor system. For a discourteous user, this would allow contention.
I don't know if other