[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: How can I lock a record using php-ldap?



You could use the sem_get(), sem_acquire() and sem_release() functions
of PHP
(at least in version 4.2.3) as a method to gain exclusive access to the
number:

Process A				Process B
semNum = sem_get(5000, 1)		semNum = sem_get(5000, 1)
sem_acquire(semNum)		sem_acquire(semNum)
	Acquires the semaphore		Blocks on the acquire
Retrieves uidNumber (say 501)		Still blocking
Increments it (now 502)			Still blocking
Sends it back to the server.			Still blocking
sem_release(semNum)			Blocking condition ends
Write record for uidNumber 501.		Acquires the semaphore
				Retrieves uidNumber (502)
				Increments it (503)
				Sends it back to the server.
				sem_release(semNum)
				Write record for uidNumber 502.

Only one process will successfully acquire the semaphore (as long as
they both
use the same key -- in this case 5000); the other will block until the
process that
successfully acquired the semaphore releases it; which should be almost
immediately.

Whether or not the semaphore needs to be removed (sem_remove()) I do
not know;
someone more versed in the usage of semaphores would have to chime in.

Mike O'Rourke

>>> "Alan Sparks" <asparks@doublesparks.net> 01/22/03 04:46am >>>
Jim C said:
> I need to be able to lock an attribute, series of entries or one
record
> and then perform several actions and then unlock the attribute.  How
can
>  this be done?

LDAP does not include a locking protocol.  It is not transactional, in
the
same sense as a transaction-capable relational database.

>
> Not being able to do this would constitute a bug because it means
that
> there will always be problems with race conditions between scripts.
> This is easily proveable.

Not really an bug, per se... more "outside the problem definition."

> ldapmodify is atomic but we cannot retrieve the number and modify it
> simultaneously. While we are doing the increment there is always the
> possibility that another script will beat us to the punch.

The LDAP client protocol definitely requires some out-of-box
thinking...
as has been shown on the list before, you need to be creative (and
live
within some constraints).

Presuming you've previously fetched the cached uidnumber as 42; client
increments the value and sends the modify operation (something like):

changetype: modify
delete: uidnumber=42
add: uidnumber=43

Since an ldapmodify operation is atomic, and only succeeds in total if
all
parts of it succeed, the above will succeed for only one updater.  The
others (with an old initial uidnumber=42) will fail the delete, and
therefore the entire "transaction."

Yes, the failed clients will have to refresh, reincrement uidnumber,
and
try again.  Such is life.

In summary, you can get around a lot of the "problems" with some
clever
workings.  But don't expect a transactional nature, since you
generally
won;t find that in LDAP.

===========
Alan Sparks, UNIX/Linux Systems Administrator   
<asparks@doublesparks.net>