adspmo
asked on
Replication Save conflicts and how best to control them
Hi
I seem to have a high number of replication conflicts.
Most of them are occuring in the Vacation tracking view. Theses dox are mostly updated via script ,however Manager intervention is also possible, however it is not a regular practise.
I have the form properties set to Merge replication conflicts.
There are three replicas of this database, New York, Toronto and London.
Any suggestions welcome
James
I seem to have a high number of replication conflicts.
Most of them are occuring in the Vacation tracking view. Theses dox are mostly updated via script ,however Manager intervention is also possible, however it is not a regular practise.
I have the form properties set to Merge replication conflicts.
There are three replicas of this database, New York, Toronto and London.
Any suggestions welcome
James
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
If you have agents scheduled on the server, only schedule it on 1 server.
If the agents run on all servers where the applciation resides, you will quickly generate *a lot* of conflicts.
cheers,
Tom
If the agents run on all servers where the applciation resides, you will quickly generate *a lot* of conflicts.
cheers,
Tom
ASKER
There are no Agents
I am wondering about the multiple editing my self
This should be a straight forward app
Create a doc, Submit for Approval Approve/Reject that is it
Will document locking prevent script updates
James
I am wondering about the multiple editing my self
This should be a straight forward app
Create a doc, Submit for Approval Approve/Reject that is it
Will document locking prevent script updates
James
I fully agree with Tom, most likely that's where the Rep.Conflicts come from.
Two ways to handle this:
- assign a server in the design of the database: this means that you have to adapt the design when you want the agent to run on a different server
- store the name of the preferred server in a Database Profile document, and check in the agent the name of the current server against the preferred one in the Profile Document; this way, you still let all servers run the agent, but it will continue only on one server; the Profile Document can easily be adapted ([EditProfile] command).
The second is a lot friendlier for the application's administrator.
Two ways to handle this:
- assign a server in the design of the database: this means that you have to adapt the design when you want the agent to run on a different server
- store the name of the preferred server in a Database Profile document, and check in the agent the name of the current server against the preferred one in the Profile Document; this way, you still let all servers run the agent, but it will continue only on one server; the Profile Document can easily be adapted ([EditProfile] command).
The second is a lot friendlier for the application's administrator.
Blast, no agents! This discussion must have had a replication conflict...
Is it R6? What's in the doc's QueryOpen event? If you have FIELD xx:= yy, this itself might save the document (seems to be a new feature of R6 :-). Weird though... Tell us more!
Is it R6? What's in the doc's QueryOpen event? If you have FIELD xx:= yy, this itself might save the document (seems to be a new feature of R6 :-). Weird though... Tell us more!
What "script" does the updating, as you mentioned? Please give us an example.
ASKER
R5.0.11
This script runs in the Glabal Section of the form
Sub Approved
'Set the session and db variables
Dim ws As New NotesUIWorkspace
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument, note As notesdocument
Dim view As NotesView
Set note = ws.CurrentDocument.Documen t
Set db = session.CurrentDatabase
Set view = db.GetView( "AvailHol")
If view Is Nothing Then
Msgbox "Cannot find view"
Exit Sub
End If
If note.HasItem("NameFull") Then
Set doc = view.GetDocumentByKey(note .NameFull( 0)) ' KEY Value passed to view
Else
Msgbox "No leave document found for this employee"
End If
If Not doc Is Nothing Then
'The conditions for processing the vacation vary greatly thus the variety of variables
'There is a field named carry over and it may contain Carried over vacation days. These need to be used first
'then the alloted vacation. If the Carry Over are not used by July then they are forfeited
If note.type(0) = "Vacation" And Month(note.StartDate(0)) >6 Then '
tmpNewDaysTotal = note.TotalDaysReq(0) 'Number of actual vacation days
tmpAllowanceAH_1 = tmpNewDaysTotal + doc.AllowanceAH_1(0) 'calculate the number of used vacation days
tmpAllowanceAH_2 = doc.allowanceAH_2(0) - tmpNewDaysTotal ' calculate the remaining vacation days
doc.AllowanceAH_1 = tmpAllowanceAH_1
doc.AllowanceAH_2 = tmpAllowanceAH_2
doc.totalAH_1 = doc.CarriedOverAH_1(0) + doc.AllowanceAH_1(0) 'Calculate the used vacation days
doc.totalAH_2 = doc.CarriedOverAH_2(0) + doc.AllowanceAH_2(0)'Calcu late the remaining vacation days
Goto SaveIt
Else
If Month(note.StartDate(0)) < 6 And note.type(0) = "Vacation" Then
If note.TotalDaysReq(0) =< doc.CarriedOverAH_2(0) Then 'Check the carryover remaing days first
doc.CarriedOverAH_1 = doc.CarriedOverAH_1(0) + note.TotalDaysReq(0) 'Calculate the used carryover days
doc.CarriedOverAH_2 = doc.CarriedOverAH(0) - note.TotalDaysReq(0) 'Calculate the remaining carryover days days
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0 )) + Cint(doc.AllowanceAH_1(0)) 'Calculate the used vacation days
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0 )) + Cint(doc.AllowanceAH_2(0)) 'Calculate the remaining vacation days
Goto SaveIt
Else
If (doc.CarriedOverAH_2(0) <> 0) And (note.TotalDaysReq(0) > doc.CarriedOverAH_2(0)) Then
tmpCarriedOverAH_2 = doc.CarriedOverAH_2(0) 'Get the current value
tmpNewDay = note.TotalDaysReq(0) - tmpCarriedOverAH_2 'Calculate the difference between the requested and the carryover
tmpAllowanceAH_2 = doc.AllowanceAH_2(0) - tmpNewDay ' calculate the remaining vacation days
tmpAllowanceAH_1 = doc.AllowanceAH_1(0) + tmpNewDay 'calculate the number of used vacation days
doc.CarriedOverAH_1 = doc.CarriedOverAH_1(0) + tmpCarriedOverAH_2 'Calculate the used carryover days
doc.CarriedOverAH_2 = 0 'Set the available to 0
doc.AllowanceAH_1 = tmpAllowanceAH_1 'Set the values
doc.AllowanceAH_2 = tmpAllowanceAH_2 'Set the values
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0 )) + Cint(doc.AllowanceAH_1(0)) 'Calculate the used vacation days
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0 )) + Cint(doc.AllowanceAH_2(0)) 'Calculate the remaining vacation days
Goto SaveIt
Else
If doc.CarriedOverAH_2(0) = 0 Then
tmpNewDaysTotal = note.TotalDaysReq(0) 'Requested days vacation
tmpAllowanceAH_1 = tmpNewDaysTotal + doc.AllowanceAH_1(0) 'calculate the number of used vacation days
tmpAllowanceAH_2 = doc.allowanceAH_2(0) - tmpNewDaysTotal ' calculate the remaining vacation days
doc.AllowanceAH_1 = tmpAllowanceAH_1 'Set the values
doc.AllowanceAH_2 = tmpAllowanceAH_2 'Set the values
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0 )) + Cint(doc.AllowanceAH_1(0)) 'Calculate the used vacation days
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0 )) + Cint(doc.AllowanceAH_2(0)) 'Calculate the remaining vacation days
Goto SaveIt
End If
End If
End If
End If
End If
If note.type(0) = "Personal" Then
tmpNewDaysTotal = note.TotalDaysReq(0) 'Number of actual personal days requested
tmpPersonalDaysAH_2 =doc.PersonalDaysAH_2(0) - tmpNewDaysTotal 'Calculate the remaining personaldays
tmpPersonalDaysAH_1 = tmpNewDaysTotal + doc.PersonalDaysAH_1(0)'Ca lculate the used days
doc.PersonalDaysAH_2 = tmpPersonalDaysAH_2 'Set the values
doc.PersonalDaysAH_1 = tmpPersonalDaysAH_1 'Set the values
Goto SaveIt
If note.type(0) = "Work From Home" Then
End If
note.ApprovalFlag_2 = "Y"
SaveIT:
doc.ComputeWithForm True, False
doc.save True, False
End If
End If
End Sub
This script runs in the Glabal Section of the form
Sub Approved
'Set the session and db variables
Dim ws As New NotesUIWorkspace
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument, note As notesdocument
Dim view As NotesView
Set note = ws.CurrentDocument.Documen
Set db = session.CurrentDatabase
Set view = db.GetView( "AvailHol")
If view Is Nothing Then
Msgbox "Cannot find view"
Exit Sub
End If
If note.HasItem("NameFull") Then
Set doc = view.GetDocumentByKey(note
Else
Msgbox "No leave document found for this employee"
End If
If Not doc Is Nothing Then
'The conditions for processing the vacation vary greatly thus the variety of variables
'There is a field named carry over and it may contain Carried over vacation days. These need to be used first
'then the alloted vacation. If the Carry Over are not used by July then they are forfeited
If note.type(0) = "Vacation" And Month(note.StartDate(0)) >6 Then '
tmpNewDaysTotal = note.TotalDaysReq(0) 'Number of actual vacation days
tmpAllowanceAH_1 = tmpNewDaysTotal + doc.AllowanceAH_1(0) 'calculate the number of used vacation days
tmpAllowanceAH_2 = doc.allowanceAH_2(0) - tmpNewDaysTotal ' calculate the remaining vacation days
doc.AllowanceAH_1 = tmpAllowanceAH_1
doc.AllowanceAH_2 = tmpAllowanceAH_2
doc.totalAH_1 = doc.CarriedOverAH_1(0) + doc.AllowanceAH_1(0) 'Calculate the used vacation days
doc.totalAH_2 = doc.CarriedOverAH_2(0) + doc.AllowanceAH_2(0)'Calcu
Goto SaveIt
Else
If Month(note.StartDate(0)) < 6 And note.type(0) = "Vacation" Then
If note.TotalDaysReq(0) =< doc.CarriedOverAH_2(0) Then 'Check the carryover remaing days first
doc.CarriedOverAH_1 = doc.CarriedOverAH_1(0) + note.TotalDaysReq(0) 'Calculate the used carryover days
doc.CarriedOverAH_2 = doc.CarriedOverAH(0) - note.TotalDaysReq(0) 'Calculate the remaining carryover days days
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0
Goto SaveIt
Else
If (doc.CarriedOverAH_2(0) <> 0) And (note.TotalDaysReq(0) > doc.CarriedOverAH_2(0)) Then
tmpCarriedOverAH_2 = doc.CarriedOverAH_2(0) 'Get the current value
tmpNewDay = note.TotalDaysReq(0) - tmpCarriedOverAH_2 'Calculate the difference between the requested and the carryover
tmpAllowanceAH_2 = doc.AllowanceAH_2(0) - tmpNewDay ' calculate the remaining vacation days
tmpAllowanceAH_1 = doc.AllowanceAH_1(0) + tmpNewDay 'calculate the number of used vacation days
doc.CarriedOverAH_1 = doc.CarriedOverAH_1(0) + tmpCarriedOverAH_2 'Calculate the used carryover days
doc.CarriedOverAH_2 = 0 'Set the available to 0
doc.AllowanceAH_1 = tmpAllowanceAH_1 'Set the values
doc.AllowanceAH_2 = tmpAllowanceAH_2 'Set the values
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0
Goto SaveIt
Else
If doc.CarriedOverAH_2(0) = 0 Then
tmpNewDaysTotal = note.TotalDaysReq(0) 'Requested days vacation
tmpAllowanceAH_1 = tmpNewDaysTotal + doc.AllowanceAH_1(0) 'calculate the number of used vacation days
tmpAllowanceAH_2 = doc.allowanceAH_2(0) - tmpNewDaysTotal ' calculate the remaining vacation days
doc.AllowanceAH_1 = tmpAllowanceAH_1 'Set the values
doc.AllowanceAH_2 = tmpAllowanceAH_2 'Set the values
doc.totalAH_1 = Cint(doc.CarriedOverAH_1(0
doc.totalAH_2 = Cint(doc.CarriedOverAH_2(0
Goto SaveIt
End If
End If
End If
End If
End If
If note.type(0) = "Personal" Then
tmpNewDaysTotal = note.TotalDaysReq(0) 'Number of actual personal days requested
tmpPersonalDaysAH_2 =doc.PersonalDaysAH_2(0) - tmpNewDaysTotal 'Calculate the remaining personaldays
tmpPersonalDaysAH_1 = tmpNewDaysTotal + doc.PersonalDaysAH_1(0)'Ca
doc.PersonalDaysAH_2 = tmpPersonalDaysAH_2 'Set the values
doc.PersonalDaysAH_1 = tmpPersonalDaysAH_1 'Set the values
Goto SaveIt
If note.type(0) = "Work From Home" Then
End If
note.ApprovalFlag_2 = "Y"
SaveIT:
doc.ComputeWithForm True, False
doc.save True, False
End If
End If
End Sub
ASKER
The problem with inheriting an application is there is stuff you do not know about
I found this while cleaning up the Agents
Sub Initialize
Dim session As New NotesSession
Set db = session.CurrentDatabase
Set collection = db.UnprocessedDocuments
Set doc = collection.GetFirstDocumen t
' ------------- The field $Conflict is added to a document to mark it as as replication conflict
Call doc.RemoveItem( "$Conflict" )
' -------------- Get the parent
If doc.IsResponse Then
Set parent = db.GetDocumentByUNID( doc.ParentDocumentUNID )
If parent.IsResponse Then
' -------------- Get the grandparent (if selected doc was a responce to a responce
Dim grandParent As NotesDocument
Set grandParent = db.GetDocumentByUNID(paren t.ParentDo cumentUNID )
Call doc.MakeResponse( grandParent )
Else
' ----------------- If there was no parent document
Call doc.RemoveItem( "$REF" )
End If
End If
Call doc.Save( True, True )
End Sub
This is a manual agent
I found this while cleaning up the Agents
Sub Initialize
Dim session As New NotesSession
Set db = session.CurrentDatabase
Set collection = db.UnprocessedDocuments
Set doc = collection.GetFirstDocumen
' ------------- The field $Conflict is added to a document to mark it as as replication conflict
Call doc.RemoveItem( "$Conflict" )
' -------------- Get the parent
If doc.IsResponse Then
Set parent = db.GetDocumentByUNID( doc.ParentDocumentUNID )
If parent.IsResponse Then
' -------------- Get the grandparent (if selected doc was a responce to a responce
Dim grandParent As NotesDocument
Set grandParent = db.GetDocumentByUNID(paren
Call doc.MakeResponse( grandParent )
Else
' ----------------- If there was no parent document
Call doc.RemoveItem( "$REF" )
End If
End If
Call doc.Save( True, True )
End Sub
This is a manual agent
ASKER
Another question
I do not see how document locking can work across servers.
I do not see how document locking can work across servers.
You can't .. it is on specific server only.
Clarify this.. did you ever get any message saying that the document has been modified by some other person and do you want to save the current one as conflict.. If you din't then it is not a save conflict.. they are mostly replication conflicts.
TO resolve this you have to look carefully at your replication schedule and adjust it to nominal value, and that value can be decided on how frequent your data changes across the servers.
Clarify this.. did you ever get any message saying that the document has been modified by some other person and do you want to save the current one as conflict.. If you din't then it is not a save conflict.. they are mostly replication conflicts.
TO resolve this you have to look carefully at your replication schedule and adjust it to nominal value, and that value can be decided on how frequent your data changes across the servers.
There is no other form, or view, that has script in it that could change the documents of the form?
A manual agent is no problem, although it might be activated from another agent.
Document locking indied doesn't work across servers. It's not the way, therefore. Focus on preventing senseless updates of your document.
Do you have a search utility for your design, like the Configurator from Ives?
Do you have/use Script tracing facilities?
Last resort for finding hidden script: create a Design Synopsis, makes good reading stuff, nice for Christmas ...
A manual agent is no problem, although it might be activated from another agent.
Document locking indied doesn't work across servers. It's not the way, therefore. Focus on preventing senseless updates of your document.
Do you have a search utility for your design, like the Configurator from Ives?
Do you have/use Script tracing facilities?
Last resort for finding hidden script: create a Design Synopsis, makes good reading stuff, nice for Christmas ...
Replication conflicts can only occur if the same document is modified on two different servers. Who does the modifying, that's what you should look for.
sjef_bosman,
> Replication conflicts can only occur if the same document is modified on two
> different servers. Who does the modifying, that's what you should look for.
That's not entirely true. If on a single server, two concurrent edits are made, you can get a replication conflict.
try this: Open a document, start editing. Have someone in the next office/cubicle open, edit, and save the same doc. Now save the doc on your station. Notes asks if you wish to save your document as a conflict document, which is identical to a replication conflict.
the same thing can happen in script. That's why there are two parameters on the NotesDocument.Save method, though who knows why they didn't just use a single three-state parameter.
> Replication conflicts can only occur if the same document is modified on two
> different servers. Who does the modifying, that's what you should look for.
That's not entirely true. If on a single server, two concurrent edits are made, you can get a replication conflict.
try this: Open a document, start editing. Have someone in the next office/cubicle open, edit, and save the same doc. Now save the doc on your station. Notes asks if you wish to save your document as a conflict document, which is identical to a replication conflict.
the same thing can happen in script. That's why there are two parameters on the NotesDocument.Save method, though who knows why they didn't just use a single three-state parameter.
Check all your forms for code in the Globals-Initialize, and form QueryOpen/PostOpen/QueryCl ose events. It is even possible to have code in other events of other forms reach out andmodify the "vacation profile"
qwaletee: isn't that a save conflict? It is the same from the user's and document's perspective since you cannot see the difference, I know. It was more a comment to Hemantha's remark that it would be a rep.conflict if it weren't caused during a save on the same server. It could also be caused by some Local db-user, having a replica on his pc, replicating every now and then with the server. I used to have some users... they almost drove me insane, for they used to use Local even when on-line.
Btw, Save has THREE parameters... hence 8-state parameter (several are useless probably).
Btw, Save has THREE parameters... hence 8-state parameter (several are useless probably).
Yes, that's a save conflict. Ever notice the diamond text is [Replication or Save Conflict]
Be sure and check one of the Conflicting documents properties for when it was last modified and by who. Check replication history and see if it matches up.
Just a suggestion.
Yoshi
Just a suggestion.
Yoshi
BTW: R6 (native) Document locking will work accross servers, using a Lock Server all the other servers can access.
I haven't used Document locking in R6 myself yet, because I've heard that it doesn't seem to work that good ... If you run R6, it may help you out though.
cheers,
Tom
I haven't used Document locking in R6 myself yet, because I've heard that it doesn't seem to work that good ... If you run R6, it may help you out though.
cheers,
Tom
Bozzie,
Correct on all counts, except that it won't help him at all.
Correct on all counts, except that it won't help him at all.
Qwaletee: since Hemantha started to make a difference between Replication Conflicts and Save Conflicts, invisible from the outside though, I continued on that one. He elaborated on the origin of a Save conflict, I tried to start discussing the Replication Conflict. Depending on the use of the form in question, it could be either, that's for adspmo to find out.
He should look at the Modified by line in the Document Properties of both the original and the conflicting document to find out who done it. Where were those 2 people, same server or different servers? On server or Local? That should tell him what the most likely origin is. If it's a Save Conflict, and he gets many of them, it must be "poor programming" or an agent on the loose. If the origin is replication, meaning that updates occur on two different servers at the same time (between replications), he has to look for programmed elements that cause the (unnecessary) updates.
He should look at the Modified by line in the Document Properties of both the original and the conflicting document to find out who done it. Where were those 2 people, same server or different servers? On server or Local? That should tell him what the most likely origin is. If it's a Save Conflict, and he gets many of them, it must be "poor programming" or an agent on the loose. If the origin is replication, meaning that updates occur on two different servers at the same time (between replications), he has to look for programmed elements that cause the (unnecessary) updates.
You can further tell which fields were updated on each side, which often gives more hints.
There's a tool for that, comparing all fields intwo documents. It's called Difference of 2 documents, where I found it I don't know anymore. Sandbox?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
R6 has an option where under these conditions, it will simply throw away one copy altogether.
I have to wonder though, why is this kind of document being updated in multiple places?