Record Locking of Documents/Replicas Across Servers

Mindwatering Incorporated

Author: Tripp W Black

Created: 04/15/2002 at 09:09 PM

 

Category:
Notes Developer Tips
LotusScript

Outdated Information. Domino has built in document locking now.
__________________________________________

Record locking across servers

Linda Heydt

08 Apr 2002, Rating
4.38 (out of 5)

The following sample illustrates how to lock a document to prevent simultaneous access by two users and to prevent update of the document on another server when replication has not occurred. In testing in the production environment, this code increased the time to open the document by 0.8 seconds.

Note: If you include the code in a subform, then all you have to do, in any application -- is plug in the subform to have the form be controlled.

Code

A locks database must be created on one server. The lock record should contain the following fields: Document ID, Created By, Originating Server, Date Modified, Expiration, and Current Edit (Yes or No). The expiration date is set two hours from the modification date, the maximum time it takes for replication to occur is two in this environment. The following code should be placed in the Queryopen and the Querymodechange events:
Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As
Variant, Continue As Variant)

On Error Goto processError

Dim session As New NotesSession
Dim dbLock As New NotesDatabase ("R5APPS04/US/testekc",
"RDHIITSlocks2.nsf")

Set db = session.currentdatabase
Set dbRemote = dbLock
Set doc = source.document

currentname = session.CommonUserName

If Not (source.EditMode) Then
Exit Sub
End If

If Isnewdoc = True Then
Exit Sub
End If

OpenLock

If createlock = "0" Then
continue = False
Exit Sub
End If

continue = True
Exit Sub

processError:
continue = False
Messagebox "Document cannot be edited." & Chr$ (10) & Chr$ (10) & "You
may only view the document." & Chr$ (10) & Chr$ (10) & "Please try
to edit the document again later.", MB_OK + 16, "Cannot Edit"
Exit Sub

End Sub

Sub OpenLock

Dim dateTime As New NotesDateTime( Now )

'If working locally, bypass the record locking
If db.server = "" Then
Exit Sub
End If

unid$ = doc.UniversalID

Set destview = dbRemote.GetView("Doc Locks")
Set destnote = destview.GetDocumentByKey(unid$, True)

If destnote Is Nothing Then
'The document is not currently locked -- create a lock record
Set lockdoc = New NotesDocument(dbRemote)
lockdoc.form = "DocLock"
lockdoc.DocId = unid$
lockdoc.LockBy = currentname
lockdoc.OrigServer = db.Server
Call dateTime.AdjustHour( 2 )
Set lockdoc.ExpDate = dateTime
lockdoc.CurrentEdit = "Yes"
lockdoc.Save True, False
createlock = "1"
'Check to verify that another user did not lock the issue at
the same time
Call destview.Refresh
Set destnote = destview.GetDocumentByKey(unid$, True)
If destnote.LockBy(0) <> currentname Then
Messagebox "Issue cannot be edited at this time." &
Chr$ (10) & Chr$ (10) & "This issue is currently being edited by: "
+ destnote.LockBy(0) & Chr$ (10) & Chr$ (10) & "You may only view
the issue (read only)." & Chr$ (10) & Chr$ (10) & "Please complete
your edit at a later time.", MB_OK + 16, "Edit Lockout"
While Not (destnote Is Nothing) And destnote.DocID(0) = unid$
If destnote.LockBy(0) = currentname Then
'destnote.Remove(True)
destnote.CurrentEdit = "No"
destnote.Save True, False
createlock = "0"
Exit Sub
End If
Set destnote = destview.GetNextDocument(destnote)
Wend
createlock = "0"
Exit Sub
End If
Else
'The document is locked
If destnote.CurrentEdit(0) = "Yes" Then
'The document is currently being edited
Messagebox "Issue cannot be edited at this time." &
Chr$ (10) & Chr$ (10) & "This issue is currently being edited by: "
+ destnote.LockBy(0) & Chr$ (10) & Chr$ (10) & "You may only view
the issue (read only)." & Chr$ (10) & Chr$ (10) & "Please complete
your edit at a later time.", MB_OK + 16, "Edit Lockout"
createlock = "0"
Exit Sub
End If
If destnote.OrigServer(0) <> db.server Then
'Check it replication has occurrred
If doc.LastModified < destnote.ModifiedDt(0) Then

Dim sname As New NotesName(destnote.OrigServer(0))
servername = sname.Common
Messagebox "Issue cannot be edited at this
time." & Chr$(10) & Chr$(10) & "This issue has been edited by: " +
destnote.LockBy(0) + " on server " + servername & Chr$(10) & "and
replication has not been completed." & Chr$(10) & Chr$(10) & "You
may only view the issue (read only)." & Chr$(10) & Chr$(10) &
"Please edit the issue on " & servername & " or wait until
replication has been completed.", MB_OK + 16, "Edit Lockout"
createlock = "0"
Exit Sub
End If
End If
'Replication has occurred and the document is not currently
open -- the document can be edited -- update the record lock
destnote.LockBy = currentname
destnote.OrigServer = db.Server
Call dateTime.AdjustHour(2)
Set destnote.ExpDate = dateTime
destnote.CurrentEdit = "Yes"
destnote.Save True, False
'Check to verify that another user did not lock the issue at
the same time
Call destview.Refresh
Set destnote = destview.GetDocumentByKey(unid$, True)
If destnote.LockBy(0) <> currentname Then
Messagebox "Issue cannot be edited at this time." &
Chr$ (10) & Chr$ (10) & "This issue is currently being edited by: "
+ destnote.LockBy(0) & Chr$ (10) & Chr$ (10) & "You may only view
the issue (read only)." & Chr$ (10) & Chr$ (10) & "Please complete
your edit at a later time", MB_OK + 16, "Edit Lockout"
createlock = "0"
Exit Sub
End If
End If
End Sub

This code should be included in the Queryclose:


'If working locally, bypass the record locking
If db.server = "" Then
Exit Sub
End If

'Unlock the document
Dim dateTime As New NotesDateTime(Now)

Set doc = source.document

unid$ = doc.UniversalID

Set destview = dbRemote.GetView("Doc Locks")
Set destnote = destview.GetDocumentByKey(unid$, True)

'modifyDate = doc.LastModified
'accessDate = doc.LastAccessed
'Msgbox modifyDate, MB_OK + MB_ICONSTOP, "Modify Date"
'Msgbox accessDate, MB_OK + MB_ICONSTOP, "Access Date"

If destnote Is Nothing Then
'The document is not locked
Exit Sub
Else
'The document is locked
If doc.LastModified > doc.LastAccessed Then
'Document was modified -- update the lock record
destnote.ModifiedDt = doc.LastModified
Call dateTime.AdjustHour(2)
Set destnote.ExpDate = dateTime
destnote.CurrentEdit = "No"
destnote.Save True, False
Else
'If createlock = "1" Then
'Document was not modified and the lock record was new
'destnote.Remove(True)
If createlock = "0" Then
'An attempt was made to open the record in edit
mode, but a lock was active
Exit Sub
Else
'Document was not modified
destnote.CurrentEdit = "No"
destnote.Save True, False
End If
End If
End If


previous page