同步框架 - 批处理

时间:2012-11-07 12:15:32

标签: microsoft-sync-framework batching

我使用同步框架2.1通过WCF(N-Tier)同步两个远程数据库(Sql Express和Sql Compact),使用批处理。

最近我收到这个日志文件,这是一个很少出现的错误,但是当它出现时会产生很多问题(似乎删除了此同步范围中包含的数据中的表失败)。 我很肯定没有人搞乱BatchingDirectory所以它应该在那里并包含所有数据。下面的错误可能与我有

的事实有关
CleanupBatchingDirectory = true

这是在应用chages之前删除的吗?

11/06/2012 14:16:49 Error ** :PosPosSync:ThreadId=7: **: 
SyncScope ErpProduct  failed
Message: An unexpected error occurred when applying batch file C:\Documents and Settings\kasse6\Application Data\POSSyncDataClient\PosSync_5b009e9008c14d0ba6a9e47726d8d620\4e77ef8c-3045-4c55-809f-014ae2b96155.batch. See the inner exception for more details.
Type   : Microsoft.Synchronization.Data.DbSyncException
Stack  :    at Microsoft.Synchronization.Data.DbSyncBatchConsumer.ApplyBatches(DbSyncScopeMetadata scopeMetadata, DbSyncSession syncSession, SyncSessionStatistics sessionStatistics)
   at Microsoft.Synchronization.Data.RelationalSyncProvider.ProcessChangeBatch(ConflictResolutionPolicy resolutionPolicy, ChangeBatch sourceChanges, Object changeDataRetriever, SyncCallbacks syncCallbacks, SyncSessionStatistics sessionStatistics)
   at Microsoft.Synchronization.KnowledgeProviderProxy.ProcessChangeBatch(CONFLICT_RESOLUTION_POLICY resolutionPolicy, ISyncChangeBatch pSourceChangeManager, Object pUnkDataRetriever, ISyncCallback pCallback, _SYNC_SESSION_STATISTICS& pSyncSessionStatistics)
   at Microsoft.Synchronization.CoreInterop.ISyncSession.Start(CONFLICT_RESOLUTION_POLICY resolutionPolicy, _SYNC_SESSION_STATISTICS& pSyncSessionStatistics)
   at Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWaySyncHelper(SyncIdFormatGroup sourceIdFormats, SyncIdFormatGroup destinationIdFormats, KnowledgeSyncProviderConfiguration destinationConfiguration, SyncCallbacks DestinationCallbacks, ISyncProvider sourceProxy, ISyncProvider destinationProxy, ChangeDataAdapter callbackChangeDataAdapter, SyncDataConverter conflictDataConverter, Int32& changesApplied, Int32& changesFailed)
   at Microsoft.Synchronization.KnowledgeSyncOrchestrator.DoOneWayKnowledgeSync(SyncDataConverter sourceConverter, SyncDataConverter destinationConverter, SyncProvider sourceProvider, SyncProvider destinationProvider, Int32& changesApplied, Int32& changesFailed)
   at Microsoft.Synchronization.KnowledgeSyncOrchestrator.Synchronize()
   at Microsoft.Synchronization.SyncOrchestrator.Synchronize()
   at PosPosSync.Local.PosPosSyncService.SynchronizeProviders(KnowledgeSyncProvider localProvider, KnowledgeSyncProvider remoteProvider, SyncDirectionOrder syncDirectionOrder)
   at PosPosSync.Local.PosPosSyncService.SyncronizeData(String scopeName, SyncDirectionOrder syncDirectionOrder)
Source : Microsoft.Synchronization
Target : Void Start(CONFLICT_RESOLUTION_POLICY, _SYNC_SESSION_STATISTICS ByRef)
------- Inner Exception ------
    Message: Could not find a part of the path 'C:\Documents and Settings\kasse6\Application Data\POSSyncDataClient\PosSync_5b009e9008c14d0ba6a9e47726d8d620\4e77ef8c-3045-4c55-809f-014ae2b96155.batch'.
    Type   : System.IO.DirectoryNotFoundException
    Stack  :    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode)
   at Microsoft.Synchronization.Data.DbSyncBatchInfoFactory.Deserialize(String batchFileName, Boolean deserializeData)
   at Microsoft.Synchronization.Data.DbSyncBatchConsumer.ReadBatchFile(UInt32 lookupLocation, UInt32 expectedNumber)
   at Microsoft.Synchronization.Data.DbSyncBatchConsumer.ReadBatchFile(UInt32 expectedNumber, String& batchFileName)
   at Microsoft.Synchronization.Data.DbSyncBatchConsumer.ApplyBatches(DbSyncScopeMetadata scopeMetadata, DbSyncSession syncSession, SyncSessionStatistics sessionStatistics)
    Source : mscorlib
    Target : Void WinIOError(Int32, System.String)

一想到,经过一段时间后,它会尝试再次同步所有数据,并根据我的日志信息,它似乎从客户端下载到服务器的所有内容:

11/06/2012 14:26:02 Info ** :PosPosSync:ThreadId=7: **: 
EndSync: ScopeName: ErpProduct
DownloadChanges: Applied - Failed: 122363 - 0
UploadChanges: Applied - Failed:  0 - 0
FinishedSync: ElapsedTime, sec: 545,0086488

2 个答案:

答案 0 :(得分:0)

尝试更改客户端上的 SqlSyncProvider.MemoryDataCacheSize (批量大小)。

当我将Batch Size设置为100kb时,我的客户端Synchronize抛出 DirectoryNotFoundException ,通常我运行500kb。我只在大型同步上看到过这种情况(例如大型数据库的初始同步)。随后的同步工作正常,因为更小。)

<强>更新

根据MS Documentation问题可能是因为数据库行超过 MemoryDataCacheSize 的110%。

  

应用程序为参与同步会话的每个提供程序指定内存数据高速缓存大小。   如果两个提供程序都指定了缓存大小,则Sync Framework会为两个提供程序使用较小的值。实际缓存大小不会超过指定最小大小的110%。 在同步会话期间,如果单个行大于110%的大小,则会话因异常终止。

答案 1 :(得分:0)

在与类似问题斗争了几年之后,我想我终于找到了解决方案。

这个&#39;无法找到路径的一部分&#39;如果定义了多个范围(并且范围足够大以使用批处理),也会发生问题,因为MS的示例代码中存在一个小错误。问题出现在SqlWebSyncService中的Dispose中,删除了此会话的批处理文件夹,但目录info变量未设置为null(这是下一个范围用来知道它是否正在创建文件夹的测试)。添加将批处理目录设置为null可以解决此问题,因为当CheckAndCreateBatchingDirectory运行时,它会将批处理目录视为空并完成制作。

private void Dispose(bool disposing)
{
try
{
    if (!this.m_disposed)
    {
        if (disposing)
        {
            if (this.m_ServerProvider != null)
            {
                this.m_ServerProvider.Dispose();
                this.m_ServerProvider = null;
            }
            if (this.m_SessionBatchingDirectory != null)
            {
                this.m_SessionBatchingDirectory.Refresh();
                if (this.m_SessionBatchingDirectory.Exists)
                {
                    try
                    {
                        this.m_SessionBatchingDirectory.Delete(true);
                    }
                    catch
                    {
                    }
                }
                this.m_SessionBatchingDirectory = null;
            }
        }
        this.m_disposed = true;
    }
}
catch (Exception exception)
{
    string message = "SqlWebSyncService Cleanup Exception: " + exception;
    LogWriter.TraceError(message, new object[0]);
    throw new FaultException<WebSyncFaultException>(new WebSyncFaultException(message, exception));
}
}

类似于客户端SqlSyncProviderProxy.EndSession

...
if (this.m_LocalBatchingDirectory != null) 
{
    this.m_LocalBatchingDirectory.Refresh();
    if (this.m_LocalBatchingDirectory.Exists) 
    {
       this.m_LocalBatchingDirectory.Delete(true);
    }
    this.m_LocalBatchingDirectory = null;
}
...

更改批量大小时,此行为会自行显示。我们将批量大小设置为70000,发现问题消失了。事后看来,这是因为第一个范围都适合单个批次,因此它不会被拆分并实现批处理。当我们将尺寸设置得更小时,我们的第一个范围(1/3)将使用批处理,当范围2启动时我们会看到这一点。