Поделиться через


Как создать моментальный снимок для публикации слиянием с параметризованными фильтрами (программирование объектов RMO)

При создании моментального снимка публикации слиянием с помощью параметризованных фильтров нужно сначала создать стандартный моментальный снимок (схему), содержащий все метаданные подписчика для подписки. Затем нужно создать часть моментального снимка, содержащую относящуюся к подписчику секцию опубликованных данных. Дополнительные сведения см. в разделе Как создать исходный моментальный снимок (программирование объектов RMO).

Для программного создания секционированных снимков можно использовать объекты RMO следующими способами.

  • Разрешите подписчикам запрашивать создание моментального снимка и его применение при первоначальной синхронизации.

  • Создайте предварительно моментальные снимки для каждой секции.

  • Создайте моментальный снимок вручную для каждого подписчика при помощи агента моментальных снимков.

ПримечаниеПримечание

Если фильтрация статьи приводит к образованию неперекрывающихся секций, уникальных для каждой подписки (если указано значение NonOverlappingSingleSubscription для PartitionOption при создании статьи публикации слиянием), метаданные очищаются при запуске агента слияния. Это означает, что срок действия секционированного снимка истекает быстрее. Если выбран этот режим, рекомендуется рассмотреть возможность разрешения подписчикам создания моментальных снимков. Дополнительные сведения см. в подразделе «Использование соответствующих параметров фильтрации» раздела Параметризованные фильтры строк.

Примечание по безопасностиПримечание по безопасности

По возможности предлагайте пользователям вводить учетные данные системы безопасности во время выполнения. Если необходимо хранить учетные данные, используйте службы шифрования, предоставляемые платформой Microsoft Windows .NET Framework.

Создание публикации, которая позволяет подписчикам инициировать формирование и доставку моментальных снимков

  1. Создайте соединение с издателем с помощью класса ServerConnection.

  2. Создайте экземпляр класса ReplicationDatabase для базы данных публикации, установите в качестве значения свойства ConnectionContext экземпляр ServerConnection, созданный на шаге 1, и вызовите метод LoadProperties. Если LoadProperties возвращает значение false, убедитесь, что база данных существует.

  3. Если свойству EnabledMergePublishing присвоено значение false, укажите значение true и вызовите CommitPropertyChanges.

  4. Создайте экземпляр класса MergePublication и укажите для него следующие свойства.

    • Соединение ServerConnection, созданное на шаге 1, в качестве значения свойства ConnectionContext.

    • Имя опубликованной базы данных в свойстве DatabaseName.

    • Имя публикации в качестве значения свойства Name.

    • Максимальное количество заданий динамических моментальных снимков, которые должны быть выполнены MaxConcurrentDynamicSnapshots. Поскольку инициированные подписчиком запросы на моментальные снимки могут возникнуть в любое время, это свойство ограничивает количество заданий агента моментальных снимков, которые могут выполняться одновременно, когда несколько подписчиков запрашивают секционированные снимки в одно и то же время. Если выполняется максимальное количество заданий, дополнительные запросы на секционированные моментальные снимки помещаются в очередь, пока одно из выполняющихся заданий не будет завершено.

    • Используйте оператор побитового логического ИЛИ (| в Visual C# и Or в Visual Basic), чтобы добавить значение AllowSubscriberInitiatedSnapshot в Attributes.

    • Поля Login и Password свойства SnapshotGenerationAgentProcessSecurity содержат учетные данные учетной записи Microsoft Windows, от имени которой выполняются задания агента моментальных снимков.

      ПримечаниеПримечание

      Рекомендуется указывать свойство SnapshotGenerationAgentProcessSecurity, если публикация создается членом предопределенной роли сервера sysadmin. Дополнительные сведения см. в разделе Модель безопасности агента репликации.

  5. Чтобы создать публикацию, вызовите метод Create.

    Примечание по безопасностиПримечание по безопасности

     При настройке издателя с удаленным распространителем значения, передаваемые для всех свойств, включая SnapshotGenerationAgentProcessSecurity, отправляются распространителю в виде обычного текста. Следует зашифровать соединение между издателем и его удаленным распространителем перед вызовом метода Create. Дополнительные сведения см. в разделе Шифрование соединений с SQL Server.

  6. Чтобы добавить статьи к публикации, используйте свойство MergeArticle. Укажите свойство FilterClause хотя бы для одной статьи, определяющей параметризованный фильтр. (Необязательно) Создайте объекты MergeJoinFilter, определяющие фильтры соединения между статьями. Дополнительные сведения см. в разделе Как определить статью (программирование объектов RMO).

  7. Если для свойства SnapshotAgentExists указано значение false, вызовите CreateSnapshotAgent, чтобы создать исходное задание агента моментального снимка для этой публикации.

  8. Вызовите метод StartSnapshotGenerationAgentJob объекта MergePublication, созданного в шаге 4. Запустится задание агента по созданию исходного моментального снимка. Дополнительные сведения о формировании исходного моментального снимка и определении пользовательского расписания для агента моментальных снимков см. в разделе Как создать исходный моментальный снимок (программирование объектов RMO).

  9. (Необязательно) Проверьте, указано ли значение true для свойства SnapshotAvailable, чтобы определить, когда исходный моментальный снимок будет готов к использованию.

  10. Когда агент слияния для подписчика подключается в первый раз, секционированный моментальный снимок создается автоматически.

Создание публикации и предварительное создание или автоматическое обновление моментальных снимков

  1. Чтобы определить публикацию слиянием, используйте экземпляр класса MergePublication. Дополнительные сведения см. в разделе Как создать публикацию (программирование объектов RMO).

  2. Чтобы добавить статьи к публикации, используйте свойство MergeArticle. Укажите свойство FilterClause хотя бы для одной статьи, определяющей параметризованный фильтр, и создайте любые объекты MergeJoinFilter, определяющие фильтры соединения между статьями. Дополнительные сведения см. в разделе Как определить статью (программирование объектов RMO).

  3. Если значение SnapshotAgentExists равно false, то для создания задания агента моментальных снимков для этой публикации вызовите метод CreateSnapshotAgent.

  4. Вызовите метод StartSnapshotGenerationAgentJob объекта MergePublication, созданного в шаге 1. Этот метод запускает задание агента по созданию исходного моментального снимка. Дополнительные сведения о создании исходного моментального снимка и определении пользовательского расписания для агента моментальных снимков см. в разделе Как создать исходный моментальный снимок (программирование объектов RMO).

  5. Проверьте, указано ли значение true для свойства SnapshotAvailable, чтобы определить, когда исходный моментальный снимок будет готов к использованию.

  6. Создайте экземпляр класса MergePartition и укажите критерии параметризованного фильтра для подписчика, используя одно или оба следующих свойства.

  7. Создайте экземпляр класса MergeDynamicSnapshotJob и укажите то же свойство, что и в шаге 6.

  8. Используйте класс ReplicationAgentSchedule, чтобы определить расписание создания фильтрованных моментальных снимков для секции подписчика.

  9. Используя экземпляр MergePublication из шага 1, вызовите метод AddMergePartition. Передайте объект MergePartition, созданный на шаге 6.

  10. Используя экземпляр MergePublication из шага 1, вызовите метод AddMergeDynamicSnapshotJob. Передайте объект MergeDynamicSnapshotJob из шага 7 и объект ReplicationAgentSchedule из шага 8.

  11. Вызовите метод EnumMergeDynamicSnapshotJobs и найдите объект MergeDynamicSnapshotJob для вновь добавленного задания секционированного моментального снимка в возвращенном массиве.

  12. Получите свойство Name для этого задания.

  13. Создайте соединение с распространителем с помощью класса ServerConnection.

  14. Создайте экземпляр класса Server объектов SMO, передав объект ServerConnection из шага 13.

  15. Создайте экземпляр класса Job, передав свойство JobServer объекта Server из шага 14 и имя задания из шага 12.

  16. Вызовите метод Start, чтобы запустить задание секционированного моментального снимка.

  17. Повторите шаги 6—16 для каждого подписчика.

Создание публикации и моментальных снимков для каждой секции вручную

  1. Чтобы определить публикацию слиянием, используйте экземпляр класса MergePublication. Дополнительные сведения см. в разделе Как создать публикацию (программирование объектов RMO).

  2. Чтобы добавить статьи в публикацию, используйте свойство MergeArticle. Укажите свойство FilterClause хотя бы для одной статьи, определяющей параметризованный фильтр, и создайте любые объекты MergeJoinFilter, определяющие фильтры соединения между статьями. Дополнительные сведения см. в разделе Как определить статью (программирование объектов RMO).

  3. Создайте исходный моментальный снимок. Дополнительные сведения см. в разделе Как создать исходный моментальный снимок (программирование объектов RMO).

  4. Создайте экземпляр класса SnapshotGenerationAgent и укажите следующие необходимые свойства.

    • Publisher — имя издателя.

    • PublisherDatabase — имя базы данных публикации.

    • Publication — имя публикации.

    • Distributor — имя распространителя.

    • PublisherSecurityMode — значение Integrated для использования встроенной проверки подлинности Windows или значение Standard для использования проверки подлинности SQL Server.

    • DistributorSecurityMode — значение Integrated для использования встроенной проверки подлинности Windows или значение Standard для использования проверки подлинности SQL Server.

  5. Укажите значение Merge в параметре ReplicationType.

  6. Задайте одно или несколько следующих свойств, чтобы определить параметры секционирования.

  7. Вызовите метод GenerateSnapshot.

  8. Повторите шаги 4—7 для каждого подписчика.

Пример

В этом примере создается публикация слиянием, позволяющая подписчикам запрашивать создание моментальных снимков.

         // Set the Publisher, publication database, and publication names.
            string publisherName = publisherInstance;
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";

            ReplicationDatabase publicationDb;
            MergePublication publication;

            // Create a connection to the Publisher.
            ServerConnection conn = new ServerConnection(publisherName);

            try
            {
                // Connect to the Publisher.
                conn.Connect();

                // Enable the database for merge publication.               
                publicationDb = new ReplicationDatabase(publicationDbName, conn);
                if (publicationDb.LoadProperties())
                {
                    if (!publicationDb.EnabledMergePublishing)
                    {
                        publicationDb.EnabledMergePublishing = true;
                    }
                }
                else
                {
                    // Do something here if the database does not exist. 
                    throw new ApplicationException(String.Format(
                        "The {0} database does not exist on {1}.",
                        publicationDb, publisherName));
                }

                // Set the required properties for the merge publication.
                publication = new MergePublication();
                publication.ConnectionContext = conn;
                publication.Name = publicationName;
                publication.DatabaseName = publicationDbName;

                // Enable precomputed partitions.
                publication.PartitionGroupsOption = PartitionGroupsOption.True;

                // Specify the Windows account under which the Snapshot Agent job runs.
                // This account will be used for the local connection to the 
                // Distributor and all agent connections that use Windows Authentication.
                publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin;
                publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword;

                // Explicitly set the security mode for the Publisher connection
                // Windows Authentication (the default).
                publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;

                // Enable Subscribers to request snapshot generation and filtering.
                publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
                publication.Attributes |= PublicationAttributes.DynamicFilters;

                // Enable pull and push subscriptions.
                publication.Attributes |= PublicationAttributes.AllowPull;
                publication.Attributes |= PublicationAttributes.AllowPush;

                if (!publication.IsExistingObject)
                {
                    // Create the merge publication.
                    publication.Create();
                    
                    // Create a Snapshot Agent job for the publication.
                    publication.CreateSnapshotAgent();
                }
                else
                {
                    throw new ApplicationException(String.Format(
                        "The {0} publication already exists.", publicationName));
                }
            }

            catch (Exception ex)
            {
                // Implement custom application error handling here.
                throw new ApplicationException(String.Format(
                    "The publication {0} could not be created.", publicationName), ex);
            }
            finally
            {
                conn.Disconnect();
            }
' Set the Publisher, publication database, and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"

Dim publicationDb As ReplicationDatabase
Dim publication As MergePublication

' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)

Try
    ' Connect to the Publisher.
    conn.Connect()

    ' Enable the database for merge publication.                
    publicationDb = New ReplicationDatabase(publicationDbName, conn)
    If publicationDb.LoadProperties() Then
        If Not publicationDb.EnabledMergePublishing Then
            publicationDb.EnabledMergePublishing = True
        End If
    Else
        ' Do something here if the database does not exist. 
        Throw New ApplicationException(String.Format( _
         "The {0} database does not exist on {1}.", _
         publicationDb, publisherName))
    End If

    ' Set the required properties for the merge publication.
    publication = New MergePublication()
    publication.ConnectionContext = conn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName

    ' Enable precomputed partitions.
    publication.PartitionGroupsOption = PartitionGroupsOption.True

    ' Specify the Windows account under which the Snapshot Agent job runs.
    ' This account will be used for the local connection to the 
    ' Distributor and all agent connections that use Windows Authentication.
    publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin
    publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword

    ' Explicitly set the security mode for the Publisher connection
    ' Windows Authentication (the default).
    publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = True

    ' Enable Subscribers to request snapshot generation and filtering.
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowSubscriberInitiatedSnapshot
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.DynamicFilters

    ' Enable pull and push subscriptions
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPull
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPush

    If Not publication.IsExistingObject Then
        ' Create the merge publication.
        publication.Create()

        ' Create a Snapshot Agent job for the publication.
        publication.CreateSnapshotAgent()
    Else
        Throw New ApplicationException(String.Format( _
            "The {0} publication already exists.", publicationName))
    End If
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
        "The publication {0} could not be created.", publicationName), ex)
Finally
    conn.Disconnect()
End Try

В этом примере вручную создается секция подписчика и фильтрованный моментальный снимок для публикации слиянием с параметризованными фильтрами строк.

            // Define the server, database, and publication names
            string publisherName = publisherInstance;
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";
            string distributorName = publisherInstance;

            MergePublication publication;
            MergePartition partition;
            MergeDynamicSnapshotJob snapshotAgentJob;
            ReplicationAgentSchedule schedule;
            
            // Create a connection to the Publisher.
            ServerConnection publisherConn = new ServerConnection(publisherName);

            // Create a connection to the Distributor to start the Snapshot Agent.
            ServerConnection distributorConn = new ServerConnection(distributorName);

            try
            {
                // Connect to the Publisher.
                publisherConn.Connect();

                // Set the required properties for the publication.
                publication = new MergePublication();
                publication.ConnectionContext = publisherConn;
                publication.Name = publicationName;
                publication.DatabaseName = publicationDbName;


                // If we can't get the properties for this merge publication, 
                // then throw an application exception.
                if (publication.LoadProperties() || publication.SnapshotAvailable)
                {
                    // Set a weekly schedule for the filtered data snapshot.
                    schedule = new ReplicationAgentSchedule();
                    schedule.FrequencyType = ScheduleFrequencyType.Weekly;
                    schedule.FrequencyRecurrenceFactor = 1;
                    schedule.FrequencyInterval = Convert.ToInt32(0x001);

                    // Set the value of Hostname that defines the data partition. 
                    partition = new MergePartition();
                    partition.DynamicFilterHostName = hostname;
                    snapshotAgentJob = new MergeDynamicSnapshotJob();
                    snapshotAgentJob.DynamicFilterHostName = hostname;

                    // Create the partition for the publication with the defined schedule.
                    publication.AddMergePartition(partition);
                    publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule);
                }
                else
                {
                    throw new ApplicationException(String.Format(
                        "Settings could not be retrieved for the publication, " +
                        " or the initial snapshot has not been generated. " +
                        "Ensure that the publication {0} exists on {1} and " +
                        "that the Snapshot Agent has run successfully.",
                        publicationName, publisherName));
                }
            }
            catch (Exception ex)
            {
                // Do error handling here.
                throw new ApplicationException(string.Format(
                    "The partition for '{0}' in the {1} publication could not be created.",
                    hostname, publicationName), ex);
            }
            finally
            {
                publisherConn.Disconnect();
                if (distributorConn.IsOpen) distributorConn.Disconnect();
            }
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"
Dim distributorName As String = publisherInstance

Dim publication As MergePublication
Dim partition As MergePartition
Dim snapshotAgentJob As MergeDynamicSnapshotJob
Dim schedule As ReplicationAgentSchedule

' Create a connection to the Publisher.
Dim publisherConn As ServerConnection = New ServerConnection(publisherName)

' Create a connection to the Distributor to start the Snapshot Agent.
Dim distributorConn As ServerConnection = New ServerConnection(distributorName)

Try
    ' Connect to the Publisher.
    publisherConn.Connect()

    ' Set the required properties for the publication.
    publication = New MergePublication()
    publication.ConnectionContext = publisherConn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName


    ' If we can't get the properties for this merge publication, 
    ' then throw an application exception.
    If (publication.LoadProperties() Or publication.SnapshotAvailable) Then
        ' Set a weekly schedule for the filtered data snapshot.
        schedule = New ReplicationAgentSchedule()
        schedule.FrequencyType = ScheduleFrequencyType.Weekly
        schedule.FrequencyRecurrenceFactor = 1
        schedule.FrequencyInterval = Convert.ToInt32("0x001", 16)

        ' Set the value of Hostname that defines the data partition. 
        partition = New MergePartition()
        partition.DynamicFilterHostName = hostname
        snapshotAgentJob = New MergeDynamicSnapshotJob()
        snapshotAgentJob.DynamicFilterHostName = hostname

        ' Create the partition for the publication with the defined schedule.
        publication.AddMergePartition(partition)
        publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule)
    Else
        Throw New ApplicationException(String.Format( _
         "Settings could not be retrieved for the publication, " + _
         " or the initial snapshot has not been generated. " + _
         "Ensure that the publication {0} exists on {1} and " + _
         "that the Snapshot Agent has run successfully.", _
         publicationName, publisherName))
    End If
Catch ex As Exception
    ' Do error handling here.
    Throw New ApplicationException(String.Format( _
     "The partition for '{0}' in the {1} publication could not be created.", _
     hostname, publicationName), ex)
Finally
    publisherConn.Disconnect()
    If distributorConn.IsOpen Then
        distributorConn.Disconnect()
    End If
End Try

В этом примере вручную запускается агент моментальных снимков для создания фильтрованного моментального снимка данных для подписчика на публикацию слиянием с параметризованными фильтрами строк.

           // Set the Publisher, publication database, and publication names.
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";
            string publisherName = publisherInstance;
            string distributorName = publisherInstance;

            SnapshotGenerationAgent agent;

            try
            {
                // Set the required properties for Snapshot Agent.
                agent = new SnapshotGenerationAgent();
                agent.Distributor = distributorName;
                agent.DistributorSecurityMode = SecurityMode.Integrated;
                agent.Publisher = publisherName;
                agent.PublisherSecurityMode = SecurityMode.Integrated;
                agent.Publication = publicationName;
                agent.PublisherDatabase = publicationDbName;
                agent.ReplicationType = ReplicationType.Merge;

                // Specify the partition information to generate a 
                // filtered snapshot based on Hostname.
                agent.DynamicFilterHostName = hostname;

                // Start the agent synchronously.
                agent.GenerateSnapshot();
            }
            catch (Exception ex)
            {
                // Implement custom application error handling here.
                throw new ApplicationException(String.Format(
                    "A snapshot could not be generated for the {0} publication."
                    , publicationName), ex);
            }
' Set the Publisher, publication database, and publication names.
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"
Dim publisherName As String = publisherInstance
Dim distributorName As String = publisherInstance

Dim agent As SnapshotGenerationAgent

Try
    ' Set the required properties for Snapshot Agent.
    agent = New SnapshotGenerationAgent()
    agent.Distributor = distributorName
    agent.DistributorSecurityMode = SecurityMode.Integrated
    agent.Publisher = publisherName
    agent.PublisherSecurityMode = SecurityMode.Integrated
    agent.Publication = publicationName
    agent.PublisherDatabase = publicationDbName
    agent.ReplicationType = ReplicationType.Merge

    ' Specify the partition information to generate a 
    ' filtered snapshot based on Hostname.
    agent.DynamicFilterHostName = hostname

    ' Start the agent synchronously.
    agent.GenerateSnapshot()
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
     "A snapshot could not be generated for the {0} publication." _
     , publicationName), ex)
End Try