Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsFormsForms ProgrammingQueriesModules / DAO / VBAReports / PrintingMacrosDatabase DesignSecurityConversionImporting / LinkingSQL Server / ADPMultiuser / NetworkingReplicationSetup / ConfigurationDeveloper ToolkitsActiveX ControlsNew UsersGeneral 1General 2
Access DirectoryToolsTutorialsUser Groups
Related Topics
SQL ServerOther DB ProductsMS OfficeMore Topics ...

MS Access Forum / Multiuser / Networking / November 2005

Tip: Looking for answers? Try searching our database.

Record Locking Schemes?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
kiln - 24 Nov 2005 21:50 GMT
I've read around here and there about record locking and have come up
with kind of an incomplete mixed bag of results. A particular app I'm
working on is more prone to concurrent record editing contention than
most I've done. Here are some bits of info an experience that I'd be
glad to hear comments on. This is jet all the way, as secured as Access
can be, Access 2000 soon-to-be Access 2003, with the regular FE BE split
format, each workstation running it's own copy of the db FE.

I've read that recordset .EditMode is kind of useless and have not been
able to get it to return a value other than 0...but that was early on in
my testing and maybe I missed something.

Probably optimistic locking is not the best for this app. If one user
has started to edit a record, I want any other user that starts to edit
the rec to be warned and prevented from continuing.

I'm intersted in hearing aobut whatever works for any reader, but what
seems to be regarded as the best route for preventing concurrent edits
is to set the form to Record Locks = Edited Record, aka pessimistic
locking, and then use a recordset to try to edit that rec; if .edit
produces an error, bail out of the second users edit attempt (probably
in the On Dirty event of the form?) But what I don't understand is that
even with tiny data populations and FE aned BE on the same pc, it takes
at least a second for the routine to cough up the msg that the rec can't
be edited and then back out the changes. How can it take so long? I'll
test more but in the meantime here is the test code (IsRecordsetLocked()
was more or less blindly copied from a post here):

Private Sub Form_Dirty(Cancel As Integer)
  Dim db As Database
  Dim rs As Recordset
  Dim strSQL As String
  Dim boolLocked As Boolean
  Dim strMsg As String
 
  Set db = CurrentDb
  strSQL = "Select qryPerson.* FROM qryPerson WHERE qryPerson.PID = " &
PID
  Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
 
  boolLocked = IsRecordsetLocked(rs, strMsg)
  MsgBox "IsRecordsetLocked " & boolLocked
  If boolLocked = True Then
     Cancel = True
  End If
End Sub

Function IsRecordsetLocked(rst As Recordset, strErrMsg As String) As
Boolean
' Checks the current record in 'rst' and retuns True if it (or the
' page its in) is locked by another user or another process on
' the same machine, otherwise False.

On Error GoTo err_IsRecordsetLocked

Const cnsLockPageSave = 3186
Const cnsLockPageRead = 3187
Const cnsLockLocalUpd = 3188
Const cnsLockExclusive = 3189
Const cnsLockRecSave = 3202
Const cnsLockRecUpd = 3218
Const cnsLockPageUpd = 3260

   IsRecordsetLocked = False
   strErrMsg = ""
'   Try to edit the current record in the recordset.
   rst.Edit
'   If we get here, No locks apply so return False.
   rst.CancelUpdate

exit_IsRecordsetLocked:
   Exit Function

err_IsRecordsetLocked:
   Select Case Err.Number
       Case cnsLockPageSave, cnsLockPageRead, cnsLockLocalUpd, _
            cnsLockExclusive, cnsLockRecSave, cnsLockRecUpd, _
            cnsLockPageUpd
           IsRecordsetLocked = True
           strErrMsg = Err.Description
       Case Else
           MsgBox "An Error has occurred (" & Err.Number & ")" & _
                  vbCrLf & Err.Description
   End Select
   Resume exit_IsRecordsetLocked

End Function
Pat Hartman(MVP) - 26 Nov 2005 17:20 GMT
Doesn't Access give you a visual clue when the record is locked by someone
else (you don't need your own code)?  In the record selector you should see
a circle with a line through it if someone else is editing the record.

I didn't examine your code in detail but Access might be taking that long
because the UpdateRetryInterval value is set too high.  Go to
Tools/Options/Advanced and try adjusting it.

> I've read around here and there about record locking and have come up
> with kind of an incomplete mixed bag of results. A particular app I'm
[quoted text clipped - 83 lines]
>
> End Function
kiln - 26 Nov 2005 22:09 GMT
Hi Pat

I don't use record selectors, and if I did they'd probably confuse end
users. There is no trappable event that occurs when the record is
blocked and the "no" or locked symbol appears. Yes I might have to go
that route if there is no bettera alternative but it's crude.

I'd thought too that the update retry setting might speed things up. But
it does not. Defaul is 250 ms, changing to 1 ms, the error does not fire
for about two seconds.

Really weird that no one seems to know how to fix this, and that so few  
have even tried to deal with it (I include myself).

> Doesn't Access give you a visual clue when the record is locked by someone
> else (you don't need your own code)?  In the record selector you should see
[quoted text clipped - 43 lines]
> > PID
> >   Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
Albert D.Kallal - 28 Nov 2005 09:23 GMT
> Really weird that no one seems to know how to fix this, and that so few
> have even tried to deal with it (I include myself).

Well, as most mentioned, if you have a record selector bar, it gives a nice
visual que..and no code. So, I am not surprised that few make any efforts
here, as ms-access can do the job for you.

However, you *can* trap a edit error. Try the following in your on current
event....I just wrote this now...but it does work ok....

Private Sub Form_Current()

  Dim rst        As DAO.Recordset

  Set rst = Me.Recordset

  If IsNull(Me.ID) = False Then
     On Error GoTo noedit
     rst.Edit
     On Error GoTo 0
  End If

  Set rst = Nothing

  Exit Sub

noedit:
  Set rst = Nothing

  MsgBox "This record is in use by another user, please try later"

End Sub

Signature

Albert D. Kallal   (Access MVP)
Edmonton, Alberta Canada
pleaseNOOSpamKallal@msn.com
http://www.members.shaw.ca/AlbertKallal

kiln - 28 Nov 2005 18:02 GMT
I never use record selectors on main forms, just like I often don't use
the build in nav buttons and a host of other sometimes useful (to me)
and sometimes not features that Access comes with. Many of us don't use
the all of the built in conveniences, there are often better ways to go
about things.

I'm not sure if you read the orig post but I certainly know that the
.edit error occurs and is trappable. The problem with .edit is (as
mentioned) that it's too slow to fire, I'd call it close to useless. For
some reason it takes about two seconds to raise the error, regardless of
how tiny, how local, etc etc etc the db and form/rs etc are configured.
At least I've not found a way to have it operate as fast as it needs to,
I am of course hoping that there is some pattern that  makes it "go".

What is not trappable (is not an error) and may or may not be detectable
is the record selector "locked" indicator showing up, or more properly
whatever internal event invokes the locked icon. It would be really cool
if whatever that is was tappable. As you know there are many such
workarounds that have been discovered, but as far as I can tell this
isn't one of them.

> > Really weird that no one seems to know how to fix this, and that so few
> > have even tried to deal with it (I include myself).
[quoted text clipped - 28 lines]
>
> End Sub
Albert D.Kallal - 29 Nov 2005 00:19 GMT
>I never use record selectors on main forms, just like I often don't use

I also don't use reocrd selctors, and in fact my forms *most* of the time
are restr5iced to one roecrd....so I do under5tand stand where you are
comming form.

> The problem with .edit is (as
> mentioned) that it's too slow to fire

Have you tried keeping a persisteacnt conenction...does that help?

> What is not trappable (is not an error) and may or may not be detectable
> is the record selector "locked" indicator showing up

Hum, does the reocrd selector show up any faster then trapping the edit?..(I
assume yes in your case).

I would as a last attempt try a persistent connection...that might help (a
persistent connection means in your startup code you open up a table to the
back end...any table.).

If the above don't work, then you could write your own locking routines....

Signature

Albert D. Kallal   (Access MVP)
Edmonton, Alberta Canada
pleaseNOOSpamKallal@msn.com
http://www.members.shaw.ca/AlbertKallal

Pat Hartman(MVP) - 29 Nov 2005 03:25 GMT
To each his own.  If I wanted to write code to control every little thing, I
would be working in VB.Net or C# or anything that paid better and got more
respect.   The big plus of Access is the things it does for you when you use
bound forms.  I feel no great compunction to reinvent the wheel or spend my
client's money to do it.

It doesn't take much to train users to use the record selector and the
navigation buttons.  I know most of them are as dumb as slugs but even a
slug can find the dish of beer in your garden in which you hope he will
drown himself.  If a client has a real aversion to the Access standard
methods, I write code (or more likely, copy it).  Otherwise, I spend my time
doing relevant things rather than trying to reproduce something Access takes
care of if we simply allow it to.

Before you spend any more time on trapping the record lock, why not try
showing the recordselector to see how long that method takes.

Also, I'm not sure the Current event is the correct place to trap the error.
You won't "see" the record lock until the other PC reading the record starts
editing it since records aren't locked until a change is started.  So two
PCs could go through the Current event for the same record without
experiencing a lock.  You may need to trap the error in the form's Dirty
event.  That event fires as soon as a user types the first character in any
field.

>>I never use record selectors on main forms, just like I often don't use
>
[quoted text clipped - 19 lines]
> If the above don't work, then you could write your own locking
> routines....
Albert D.Kallal - 29 Nov 2005 07:05 GMT
> To each his own.  If I wanted to write code to control every little thing,
> I would be working in VB.Net or C# or anything that paid better and got
> more respect.   The big plus of Access is the things it does for you when
> you use bound forms.  I feel no great compunction to reinvent the wheel or
> spend my client's money to do it.

I agree with the above assessment.

> Also, I'm not sure the Current event is the correct place to trap the
> error.

Ditto. My code snip is only a proof of concept. About the "only" use of my
code example would be to test to see the "delay" is reduced, or eliminated.
If the delay goes away, then I would consider expanding on the .edit
idea..but only then... (and, likey the on-dirty event would be a possbile
approach).

Depending on the design of the application, rolling ones own locking
routines is a reasonable approach. In fact, I wrote a set of routines back
for a application I did in access 97. (record locking was at the page level
back then).

The criteria for locking code needs to be:

   Easy to implement for any form (ie: a generalized solution that requites
VERY little code)

  The lock table used needs to use the built in locking mechanism to avoid
conflicts

   The design needs to be such as to not cause any additional bloat to the
file.

   Since this approach will have a lock table, then the "message" displayed
can include the workstation, and user who
   currently has the record locked.

   Only the "parent" record need be locked, since that is the "only" way to
edit child records.

I believe that the above design goals are quite easily obtained if certain
restrictions in how forms will be used is very obtainable. (My code worked
very well for me, and this code continues to be used daily in a a2003
application now).

However, at the end of the day...the comments that one needs to work within
the constraints of what ms-access offers is likely the best approach.

I am willing to post my locking code..but it does need some "explain" on how
to use it...

Signature

Albert D. Kallal   (Access MVP)
Edmonton, Alberta Canada
pleaseNOOSpamKallal@msn.com
http://www.members.shaw.ca/AlbertKallal

kiln - 29 Nov 2005 08:09 GMT
> >I never use record selectors on main forms, just like I often don't use
>
[quoted text clipped - 18 lines]
>
> If the above don't work, then you could write your own locking routines....

I'll try the persistant connection in the AM. I have seen it make a diff
in some situation or other.

The record selector "lock" indicator is virtually instantaneous.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.