How to synchronize a replica


This sample demonstrates how to synchronize a replica in a connected environment. A connected environment means that the geodatabases involved are on the same network. This may be a LAN or a WAN if using ArcGIS server.
The sample includes a number of routines that demonstrate how to synchronize a replica under different circumstances. For example, one routine synchronizes a check-out replica (check in) between a local ArcSDE server and a personal geodatabase. Another synchronizes a 2 way replica between two ArcSDE servers over a WAN using ArcGIS server. In each case the same generic function is called to synchronize the replica.
To purpose of this sample is to provide some code that you can adjust to suit your needs. For example, all of the routines resolve conflicts in favor of the geodatabase that is importing the data. You may want to set this to a different conflict resolution policy. Also the replica geodatabases and the replica names are hard coded and need to be adjusted.

How to use

  1. Paste the code into VBA in ArcMap or ArcCatalog. The code can also be associated with a command click events in Visual Basic.
  2. Find the routine that performs the type of replica synchronization needed.
  3. Adjust the code appropriately and run the routine. The code below has hard coded server connections, synchronization options and replica names.
[VBA]
'++ Synchronize a check-out replica with ArcSDE as the parent and a personal geodatabase
'++ as the child. Both geodatabases are accessed over the LAN.

Sub Sync_Checkout_ArcSDE_PGDB()
    
    Dim pGDSparent As IGeoDataServer
    Dim pGDSparentInit As IGeoDataServerInit
    Dim pGDSchild As IGeoDataServer
    Dim pGDSchildInit As IGeoDataServerInit
    Dim bOK As Boolean
    
    '++ Initialize the parent
    Set pGDSparent = New GeoDataServer
    Set pGDSparentInit = pGDSparent
    pGDSparentInit.InitFromConnectionString "SERVER=bobmk;INSTANCE=5165;VERSION=sde.DEFAULT;USER=qa;PASSWORD=qa;DATABASE=qa1"
    
    '++ Initialize the child
    '++ (note: this must reference an already exisiting and empty personal geodatabase)
    Set pGDSchild = New GeoDataServer
    Set pGDSchildInit = pGDSchild
    pGDSchildInit.InitFromFile "d:\temp\CO_child.mdb"
    
    '++ Sync the replica. In this case we want conflicts reconciled in favor of the parent,
    '++ to sync from child to parent (check in) and use row level conflicts
    bOK = Sync_Replica(pGDSparent, pGDSchild, "sample_COReplica", _
          esriRAResolveConflictsInFavorOfReplica1, esriReplicaSynchronizeFromReplica2ToReplica1, False)
    MsgBox "Replica synced successfully: " & bOK
    
End Sub

'++ Synchronize a 2 way replica between two ArcSDE servers. Both geodatabases are
'++ accessed over the LAN. This synchronization sends changes in both directions.

Sub Sync_2wayReplica_LAN()
    
    Dim pGDSparent As IGeoDataServer
    Dim pGDSparentInit As IGeoDataServerInit
    Dim pGDSchild As IGeoDataServer
    Dim pGDSchildInit As IGeoDataServerInit
    Dim bOK As Boolean
    
    '++ Initialize the parent
    Set pGDSparent = New GeoDataServer
    Set pGDSparentInit = pGDSparent
    pGDSparentInit.InitFromConnectionString "SERVER=bobmk;INSTANCE=5165;VERSION=sde.DEFAULT;USER=qa;PASSWORD=qa;DATABASE=qa1"
    
    '++ Initialize the child
    Set pGDSchild = New GeoDataServer
    Set pGDSchildInit = pGDSchild
    pGDSchildInit.InitFromConnectionString "SERVER=bobmk;INSTANCE=5166;VERSION=sde.DEFAULT;USER=qa;PASSWORD=qa;DATABASE=qa2"
    
    '++ Sync the replica. In this case we want conflicts reconciled in favor of the parent,
    '++ to sync in both directions and use row level conflicts
    bOK = Sync_Replica(pGDSparent, pGDSchild, "sample_2WayRep_LAN", _
          esriReplicaResolveConflictsInFavorOfDatabaseChanges, esriReplicaSynchronizeBoth, False)
    MsgBox "Replica synced successfully: " & bOK
    
End Sub

'++ Synchronize a 2 way replica between two ArcSDE servers. Remote GeoDataServer
'++ objects served by ArcGIS server over the WAN are used. This synchronization sends changes in both directions.

Sub Sync_2wayReplica_WAN()
    
    Dim pGDSparent As IGeoDataServer
    Dim pGDSchild As IGeoDataServer
    Dim bOK As Boolean
    Dim scf As IAGSServerConnectionFactory
    Dim cprops As IPropertySet
    Dim psc As IAGSServerConnection
    Dim pSons As IAGSEnumServerObjectName
    Dim pSon As IAGSServerObjectName
    Dim pName As IName
    
    '++ Get the server objects published on the the ArcGIS server named bobmk
    Set cprops = New PropertySet
    cprops.SetProperty "Machine", "baza"
    Set scf = New AGSServerConnectionFactory
    Set psc = scf.Open(cprops, 0)
    Set pSons = psc.ServerObjectNames
    pSons.Reset
    
    '++ Get the parent server object
    Set pSon = pSons.Next
    Do Until pSon.Name = "bobmk_5165_qa"
        Set pSon = pSons.Next
    Loop
    Set pName = pSon
    Set pGDSparent = pName.Open
    
    '++ Get the server objects published on the the ArcGIS server named baza
    Set cprops = New PropertySet
    cprops.SetProperty "Machine", "bobmk"
    Set scf = New AGSServerConnectionFactory
    Set psc = scf.Open(cprops, 0)
    Set pSons = psc.ServerObjectNames
    pSons.Reset
    
    '++ Get the child server object
    Set pSon = pSons.Next
    Do Until pSon.Name = "bobmk_5166_qa"
        Set pSon = pSons.Next
    Loop
    Set pName = pSon
    Set pGDSchild = pName.Open
    
    '++ Sync the replica. In this case we want conflicts reconciled in favor of the parent,
    '++ to sync in both directions and use row level conflicts
    bOK = Sync_Replica(pGDSparent, pGDSchild, "sample_2WayRep_WAN", _
          esriReplicaResolveConflictsInFavorOfDatabaseChanges, esriReplicaSynchronizeBoth, False)
    MsgBox "Replica synced successfully: " & bOK
    
End Sub

'++ Syncs a replica

Function Sync_Replica(pGDSparent As IGeoDataServer, pGDSchild As IGeoDataServer, sRepName As String, _
                      conflictPolicy As esriReplicationAgentReconcilePolicy, syncDir As esriReplicaSynchronizeDirection, bolConflicts As Boolean) As Boolean
    
    On Error GoTo eh
    
    Dim pRepAgent As IReplicationAgent
    Dim pGPReplicaPar As IGPReplica
    Dim pGPReplicaChild As IGPReplica
    Dim pGPReplicas As IGPReplicas
    Dim i As Integer
    Dim sBaseName As String
    
    '++ Get the parent replica
    Set pGPReplicas = pGDSparent.Replicas
    For i = 0 To pGPReplicas.Count - 1
        Set pGPReplicaPar = pGPReplicas.Element(i)
        sBaseName = Right(pGPReplicaPar.Name, Len(pGPReplicaPar.Name) - InStr(pGPReplicaPar.Name, "."))
        If sBaseName = sRepName Then Exit For
    Next i
    
    '++ Get the child replica
    Set pGPReplicas = pGDSchild.Replicas
    For i = 0 To pGPReplicas.Count - 1
        Set pGPReplicaChild = pGPReplicas.Element(i)
        sBaseName = Right(pGPReplicaChild.Name, Len(pGPReplicaChild.Name) - InStr(pGPReplicaChild.Name, "."))
        If sBaseName = sRepName Then Exit For
    Next i
    
    '++ Sync the replica
    Set pRepAgent = New ReplicationAgent
    pRepAgent.SynchronizeReplica pGDSparent, pGDSchild, pGPReplicaPar, pGPReplicaChild, _
        conflictPolicy, syncDir, bolcol
    
    Sync_Replica = True
    Exit Function
eh:
    MsgBox "Sync replica errored: " & Err.Description & " : error number: " & Err.Number
End Function