如何:使用參數化篩選建立合併式發行集的快照集 (RMO 程式設計)
在使用參數化篩選產生合併式發行集的快照集時,您必須先產生一個標準 (結構描述) 快照集,其中包含訂閱的所有訂閱者中繼資料。然後,您會產生包含發行資料之訂閱者特有資料分割的快照集部分。如需詳細資訊,請參閱<如何:建立初始快照集 (RMO 程式設計)>。
您可以透過以下方式,以程式設計的方式使用「複寫管理物件」(RMO) 來產生分割快照集。
允許訂閱者在首次執行同步處理時,要求快照集產生和應用程式。
為每個資料分割預先產生快照集。
執行「快照集代理程式」為每個訂閱者手動產生快照集。
[!附註]
當篩選發行項產生了對每個訂閱而言是唯一的非重疊資料分割時 (在建立合併發行項時,針對 PartitionOption 指定 NonOverlappingSingleSubscription 的值),則只要合併代理程式一執行,就會清除中繼資料。這表示分割快照集會更快過期。當使用這個選項時,您應該考慮允許訂閱者要求產生快照集。如需詳細資訊,請參閱<參數化資料列篩選器>主題中的「使用適當的篩選選項」一節。
安全性注意事項 |
---|
可能的話,系統會在執行階段提示使用者輸入安全性認證。如果您必須儲存認證,請使用 Microsoft Windows .NET Framework 提供的<密碼編譯服務>(英文)。 |
建立可讓訂閱者初始化快照集產生和傳遞的發行集
使用 ServerConnection 類別建立與發行者的連接。
為發行集資料庫建立 ReplicationDatabase 類別的執行個體、將 ConnectionContext 屬性設定為步驟 1 中的 ServerConnection 執行個體,並呼叫 LoadProperties 方法。如果 LoadProperties 傳回 false,請確認此資料庫確實存在。
如果 EnabledMergePublishing 屬性為 false,請將它設定為 true 然後呼叫 CommitPropertyChanges。
建立 MergePublication 類別的執行個體,並為此物件設定下列屬性:
將 ConnectionContext 設定為步驟 1 中的 ServerConnection。
將 DatabaseName 設為發行的資料庫名稱。
將 Name 設定為發行集名稱。
將 MaxConcurrentDynamicSnapshots 設定為動態快照集作業的最大數目。由於訂閱者起始的快照集要求可在任何時間發生,所以當多個訂閱者同時要求其分割快照集時,這個屬性會限制可以同時執行的快照集代理程式作業數目。當正在執行最大的作業數目時,其他分割快照集要求會排入佇列中,直到其中一個執行中的作業完成為止。
使用位元邏輯 OR (Visual C# 中為 | 且 Visual Basic 中為 Or) 運算子,將 AllowSubscriberInitiatedSnapshot 值加入 Attributes。
SnapshotGenerationAgentProcessSecurity 的 Login 和 Password 欄位,可提供執行快照集代理程式作業所使用之 Microsoft Windows 帳戶的認證。
[!附註]
當發行集是由 sysadmin 固定伺服器角色的成員所建立時,建議您設定 SnapshotGenerationAgentProcessSecurity。如需詳細資訊,請參閱<複寫代理程式安全性模型>。
呼叫 Create 方法來建立發行集。
安全性注意事項 當利用遠端散發者來設定發行者時,提供給所有屬性的值 (包括 SnapshotGenerationAgentProcessSecurity) 都會以純文字的方式傳給散發者。您應該先加密發行者及其遠端散發者之間的連接,再呼叫 Create 方法。如需詳細資訊,請參閱<加密 SQL Server 的連接>。
使用 MergeArticle 屬性將發行項加入發行集中。至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性。(選擇性) 建立可在發行項之間定義聯結篩選的 MergeJoinFilter 物件。如需詳細資訊,請參閱<如何:定義發行項 (RMO 程式設計)>。
如果 SnapshotAgentExists 的值是 false,請呼叫 CreateSnapshotAgent 來針對這個發行集建立初始快照集代理程式作業。
呼叫步驟 4 中建立之 MergePublication 物件的 StartSnapshotGenerationAgentJob 方法。這樣會啟動可產生初始快照集的代理程式作業。如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱<如何:建立初始快照集 (RMO 程式設計)>。
(選擇性) 檢查是否有為 SnapshotAvailable 屬性設定 true 的值,以判斷初始快照集何時可準備好供人使用。
當訂閱者的合併代理程式第一次連接時,會自動產生分割快照集。
建立發行集及預先產生或自動重新整理快照集
使用 MergePublication 類別的執行個體來定義合併式發行集。如需詳細資訊,請參閱<如何:建立發行集 (RMO 程式設計)>。
使用 MergeArticle 屬性將發行項加入發行集中。至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性,並建立可在兩個發行項之間定義聯結篩選的任何 MergeJoinFilter 物件。如需詳細資訊,請參閱<如何:定義發行項 (RMO 程式設計)>。
如果 SnapshotAgentExists 的值是 false,請呼叫 CreateSnapshotAgent 來針對這個發行集建立快照集代理程式作業。
呼叫步驟 1 中建立之 MergePublication 物件的 StartSnapshotGenerationAgentJob 方法。這個方法會啟動可產生初始快照集的代理程式作業。如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱<如何:建立初始快照集 (RMO 程式設計)>。
檢查是否有為 SnapshotAvailable 屬性設定 true 的值,以判斷初始快照集何時可準備好供人使用。
建立 MergePartition 類別的執行個體,並使用以下其中一個或兩個屬性來為訂閱者設定參數化篩選準則:
如果訂閱者的資料分割是由 SUSER_SNAME (Transact-SQL) 的結果所定義,請使用 DynamicFilterLogin。
如果訂閱者的資料分割是由 HOST_NAME (Transact-SQL) 的結果或這個函數的多載所定義,請使用 DynamicFilterHostName。
建立 MergeDynamicSnapshotJob 類別的執行個體,並設定與步驟 6 中相同的屬性。
使用 ReplicationAgentSchedule 類別來定義排程,以針對訂閱者資料分割產生篩選的快照集。
使用步驟 1 中的 MergePublication 執行個體,呼叫 AddMergePartition。傳遞步驟 6 中的 MergePartition 物件。
使用步驟 1 中的 MergePublication 執行個體,呼叫 AddMergeDynamicSnapshotJob 方法。傳遞步驟 7 中的 MergeDynamicSnapshotJob 物件及步驟 8 中的 ReplicationAgentSchedule 物件。
呼叫 EnumMergeDynamicSnapshotJobs 並在 MergeDynamicSnapshotJob 物件中找出傳回的陣列中新加入的分割快照集作業。
取得此作業的 Name 屬性。
使用 ServerConnection 類別建立與散發者的連接。
建立 SQL Server Management Objects (SMO) Server 類別的執行個體,傳遞步驟 13 中的 ServerConnection 物件。
建立 Job 類別的執行個體,傳遞步驟 14 中 Server 的 JobServer 屬性及步驟 12 中的作業名稱。
呼叫 Start 方法來啟動分割快照集作業。
對每一個訂閱者重複步驟 6-16。
針對每一個資料分割建立發行集及手動建立快照集
使用 MergePublication 類別的執行個體來定義合併式發行集。如需詳細資訊,請參閱<如何:建立發行集 (RMO 程式設計)>。
使用 MergeArticle 屬性將發行項加入發行集中。至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性,並建立可在兩個發行項之間定義聯結篩選的任何 MergeJoinFilter 物件。如需詳細資訊,請參閱<如何:定義發行項 (RMO 程式設計)>。
產生初始快照集。如需詳細資訊,請參閱<如何:建立初始快照集 (RMO 程式設計)>。
建立 SnapshotGenerationAgent 類別的執行個體,並設定下列必要的屬性:
Publisher - 發行者的名稱
PublisherDatabase - 發行集資料庫的名稱
Publication - 發行集的名稱
Distributor - 散發者的名稱
PublisherSecurityMode - 代表使用「Windows 整合式驗證」的 Integrated 值,或使用「SQL Server 驗證」的 Standard 值。
DistributorSecurityMode - 代表使用「Windows 整合式驗證」的 Integrated 值,或使用「SQL Server 驗證」的 Standard 值。
為 ReplicationType 設定 Merge 的值。
設定以下其中一個或多個屬性來定義資料分割參數:
如果訂閱者的資料分割是由 SUSER_SNAME (Transact-SQL) 的結果所定義,請使用 DynamicFilterLogin。
如果訂閱者的資料分割是由 HOST_NAME (Transact-SQL) 的結果或這個函數的多載所定義,請使用 DynamicFilterHostName。
呼叫 GenerateSnapshot 方法。
對每一個訂閱者重複步驟 4-7。
範例
此範例會建立允許訂閱者要求產生快照集的合併式發行集。
// Set the Publisher, publication database, and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks";
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 = "AdventureWorks"
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 = "AdventureWorks";
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 = "AdventureWorks"
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 = "AdventureWorks";
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 = "AdventureWorks"
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