Procedura: Creazione di uno snapshot per una pubblicazione di tipo merge con filtri con parametri (programmazione RMO)
Quando si genera uno snapshot per una pubblicazione di tipo merge utilizzando filtri con parametri, è necessario innanzitutto generare uno snapshot standard (schema) che contiene tutti i metadati del Sottoscrittore per la sottoscrizione. Generare quindi la parte dello snapshot che contiene la partizione dei dati pubblicati specifica del Sottoscrittore. Per ulteriori informazioni, vedere Procedura: Creazione dello snapshot iniziale (programmazione RMO).
È possibile utilizzare oggetti RMO (Replication Management Objects) per generare snapshot partizionati a livello di programmazione nelle modalità seguenti:
Consentire ai Sottoscrittori di richiedere la generazione e l'applicazione degli snapshot alla prima sincronizzazione.
Pregenerare uno snapshot per ogni partizione.
Generare manualmente uno snapshot per ogni Sottoscrittore eseguendo l'agente snapshot.
Nota
Quando il filtro di un articolo produce partizioni non sovrapposte univoche per ogni sottoscrizione (specificando un valore NonOverlappingSingleSubscription per PartitionOption nel caso della creazione di un articolo di tipo merge), i metadati vengono puliti ogni volta che viene eseguito l'agente di merge. Lo snapshot partizionato scade quindi più rapidamente. Quando si utilizza questa opzione, è consigliabile consentire ai Sottoscrittori di richiedere la generazione degli snapshot. Per ulteriori informazioni, vedere la sezione relativa all'utilizzo delle opzioni di filtro appropriate nell'argomento Filtri di riga con parametri.
Nota sulla sicurezza |
---|
Se possibile, richiedere agli utenti di immettere le credenziali di protezione in fase di esecuzione. Se è necessario archiviare le credenziali, utilizzare i servizi di crittografia offerti da Microsoft Windows .NET Framework. |
Per creare una pubblicazione che consente ai Sottoscrittori di avviare la generazione e il recapito di snapshot
Creare una connessione al server di pubblicazione tramite la classe ServerConnection.
Creare un'istanza della classe ReplicationDatabase per il database di pubblicazione, impostare la proprietà ConnectionContext sull'istanza di ServerConnection indicata nel passaggio 1, quindi chiamare il metodo LoadProperties. Se LoadProperties restituisce false, verificare che il database esista.
Se la proprietà EnabledMergePublishing è false, impostarla su true e chiamare CommitPropertyChanges.
Creare un'istanza della classe MergePublication e impostare le proprietà seguenti per questo oggetto:
Oggetto ServerConnection indicato nel passaggio 1 per ConnectionContext.
Nome del database di pubblicazione per DatabaseName.
Nome per la pubblicazione per Name.
Numero massimo di processi di snapshot dinamici da eseguire per MaxConcurrentDynamicSnapshots. Poiché le richieste di snapshot avviate dal Sottoscrittore possono verificarsi in qualsiasi momento, questa proprietà limita il numero di processi dell'agente snapshot che possono essere eseguiti simultaneamente quando più Sottoscrittori richiedono il rispettivo snapshot partizionato contemporaneamente. Quando è in esecuzione il numero massimo di processi, le richieste aggiuntive di snapshot partizionati vengono inserite nella coda fino al completamento di uno dei processi.
Utilizzare l'operatore logico OR bit per bit (| in Visual C# e Or in Visual Basic) per aggiungere il valore AllowSubscriberInitiatedSnapshot a Attributes.
Campi Login e Password di SnapshotGenerationAgentProcessSecurity per fornire le credenziali per l'account di Microsoft Windows con cui verrà eseguito il processo dell'agente snapshot.
Nota
È consigliabile impostare SnapshotGenerationAgentProcessSecurity quando la pubblicazione viene creata da un membro del ruolo predefinito del server sysadmin. Per ulteriori informazioni, vedere Modello di sicurezza dell'agente di replica.
Chiamare il metodo Create per creare la pubblicazione.
Nota sulla sicurezza Quando si configura un server di pubblicazione con un server di distribuzione remoto, i valori specificati per tutte le proprietà, inclusa SnapshotGenerationAgentProcessSecurity, vengono inviati al server di distribuzione come testo normale. È consigliabile crittografare la connessione tra il server di pubblicazione e il server di distribuzione remoto prima di chiamare il metodo Create. Per ulteriori informazioni, vedere Crittografia delle connessioni a SQL Server.
Utilizzare la proprietà MergeArticle per aggiungere articoli alla pubblicazione. Specificare la proprietà FilterClause per almeno un articolo che definisce il filtro con parametri. (Facoltativo) Creare oggetti MergeJoinFilter che definiscono i filtri join tra gli articoli. Per ulteriori informazioni, vedere Procedura: Definizione di un articolo (programmazione RMO).
Se il valore di SnapshotAgentExists è false, chiamare CreateSnapshotAgent per creare il processo dell'agente snapshot iniziale per questa pubblicazione.
Chiamare il metodo StartSnapshotGenerationAgentJob dell'oggetto MergePublication creato nel passaggio 4. In questo modo viene avviato il processo dell'agente che genera lo snapshot iniziale. Per ulteriori informazioni sulla generazione di uno snapshot iniziale e sulla definizione di una pianificazione personalizzata per l'agente snapshot, vedere Procedura: Creazione dello snapshot iniziale (programmazione RMO).
(Facoltativo) Verificare la presenza di un valore true per la proprietà SnapshotAvailable per determinare quando lo snapshot iniziale è pronto per l'utilizzo.
La prima volta che l'agente di merge per un Sottoscrittore si connette, verrà generato automaticamente uno snapshot partizionato.
Per creare una pubblicazione e pregenerare o aggiornare automaticamente gli snapshot
Utilizzare un'istanza della classe MergePublication per definire una pubblicazione di tipo merge. Per ulteriori informazioni, vedere Procedura: Creazione di una pubblicazione (programmazione RMO).
Utilizzare la proprietà MergeArticle per aggiungere articoli alla pubblicazione. Specificare la proprietà FilterClause per almeno un articolo che definisce il filtro con parametri, quindi creare eventuali oggetti MergeJoinFilter che definiscono filtri join tra gli articoli. Per ulteriori informazioni, vedere Procedura: Definizione di un articolo (programmazione RMO).
Se il valore di SnapshotAgentExists è false, chiamare CreateSnapshotAgent per creare il processo dell'agente snapshot per questa pubblicazione.
Chiamare il metodo StartSnapshotGenerationAgentJob dell'oggetto MergePublication creato nel passaggio 1. Questo metodo avvia il processo dell'agente che genera lo snapshot iniziale. Per ulteriori informazioni sulla generazione di uno snapshot iniziale e sulla definizione di una pianificazione personalizzata per l'agente snapshot, vedere Procedura: Creazione dello snapshot iniziale (programmazione RMO).
(Facoltativo) Verificare la presenza di un valore true per la proprietà SnapshotAvailable per determinare quando lo snapshot iniziale è pronto per l'utilizzo.
Creare un'istanza della classe MergePartition e impostare i criteri di filtro con parametri per il Sottoscrittore utilizzando una o entrambe le proprietà seguenti:
Se la partizione del Sottoscrittore è definita dal risultato di SUSER_SNAME (Transact-SQL), utilizzare DynamicFilterLogin.
Se la partizione del Sottoscrittore è definita dal risultato di HOST_NAME (Transact-SQL) o da un overload di questa funzione, utilizzare DynamicFilterHostName.
Creare un'istanza della classe MergeDynamicSnapshotJob e impostare la stessa proprietà indicata nel passaggio 6.
Utilizzare la classe ReplicationAgentSchedule per definire una pianificazione per la generazione dello snapshot filtrato per la partizione del Sottoscrittore.
Utilizzando l'istanza di MergePublication indicata nel passaggio 1, chiamare AddMergePartition. Passare l'oggetto MergePartition indicato nel passaggio 6.
Utilizzando l'istanza di MergePublication indicata nel passaggio 1, chiamare il metodo AddMergeDynamicSnapshotJob. Passare l'oggetto MergeDynamicSnapshotJob indicato nel passaggio 7 e l'oggetto ReplicationAgentSchedule indicato nel passaggio 8.
Chiamare EnumMergeDynamicSnapshotJobs e individuare l'oggetto MergeDynamicSnapshotJob per il processo di snapshot partizionato appena aggiunto nella matrice restituita.
Ottenere la proprietà Name per il processo.
Creare una connessione al server di distribuzione tramite la classe ServerConnection.
Creare un'istanza della classe Server SMO (SQL Server Management Objects) passando l'oggetto ServerConnection indicato nel passaggio 13.
Creare un'istanza della classe Job passando la proprietà JobServer dell'oggetto Server indicato nel passaggio 14 e il nome del processo indicato nel passaggio 12.
Chiamare il metodo Start per avviare il processo di snapshot partizionato.
Ripetere i passaggi da 6 a 16 per ogni Sottoscrittore.
Per creare una pubblicazione e creare manualmente gli snapshot per ogni partizione
Utilizzare un'istanza della classe MergePublication per definire una pubblicazione di tipo merge. Per ulteriori informazioni, vedere Procedura: Creazione di una pubblicazione (programmazione RMO).
Utilizzare la proprietà MergeArticle per aggiungere articoli alla pubblicazione. Specificare la proprietà FilterClause per almeno un articolo che definisce il filtro con parametri, quindi creare eventuali oggetti MergeJoinFilter che definiscono i filtri join tra gli articoli. Per ulteriori informazioni, vedere Procedura: Definizione di un articolo (programmazione RMO).
Generare lo snapshot iniziale. Per ulteriori informazioni, vedere Procedura: Creazione dello snapshot iniziale (programmazione RMO).
Creare un'istanza della classe SnapshotGenerationAgent e impostare le seguenti proprietà obbligatorie:
Publisher: nome del server di pubblicazione
PublisherDatabase: nome del database di pubblicazione
Publication: nome della pubblicazione
Distributor: nome del server di distribuzione
PublisherSecurityMode: valore di Integrated per utilizzare l'autenticazione integrata di Windows o valore di Standard per utilizzare l'autenticazione di SQL Server.
DistributorSecurityMode: valore di Integrated per utilizzare l'autenticazione integrata di Windows o valore di Standard per utilizzare l'autenticazione di SQL Server.
Impostare un valore di Merge per ReplicationType.
Impostare una o più delle seguenti proprietà per definire i parametri di partizionamento:
Se la partizione del Sottoscrittore è definita dal risultato di SUSER_SNAME (Transact-SQL), utilizzare DynamicFilterLogin.
Se la partizione del Sottoscrittore è definita dal risultato di HOST_NAME (Transact-SQL) o da un overload di questa funzione, utilizzare DynamicFilterHostName.
Chiamare il metodo GenerateSnapshot.
Ripetere i passaggi da 4 a 7 per ogni Sottoscrittore.
Esempio
In questo esempio viene creata una pubblicazione di tipo merge che consente ai Sottoscrittori di richiedere la generazione di snapshot.
// 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
In questo esempio vengono creati manualmente la partizione del Sottoscrittore e lo snapshot filtrato per una pubblicazione di tipo merge con filtri di riga con parametri.
// 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
In questo esempio viene avviato manualmente l'agente snapshot per generare lo snapshot di dati filtrati per un Sottoscrittore in una pubblicazione di tipo merge con filtri di riga con parametri.
// 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
Vedere anche