Link to home
Start Free TrialLog in
Avatar of adspmo
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

SOLUTION
Avatar of HemanthaKumar
HemanthaKumar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of qwaletee
qwaletee

Merge conflicts does absolutely nothing if the same field is updated in the two copies being merged. When you have a history field, and any change to the doc causes a change to the history field, then merge conflicts is USELESS, because all updates will have changed this field, and there is no way to merge the fields.  Merge conflicts simply means, take the changed fields from one side and the changed fields from the other side, and aply them equaly if there is no overlap."

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?
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
Avatar of adspmo

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
Avatar of Sjef Bosman
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.
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!
What "script" does the updating, as you mentioned? Please give us an example.
Avatar of adspmo

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.Document
      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)'Calculate 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)'Calculate 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
Avatar of adspmo

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.GetFirstDocument
' ------------- 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(parent.ParentDocumentUNID )
                  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
Avatar of adspmo

ASKER

Another question

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.
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 ...
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.
Check all your forms for code in the Globals-Initialize, and form QueryOpen/PostOpen/QueryClose 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).
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
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
Bozzie,

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.
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
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial