1

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

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

CleanupBatchingDirectory = true

这是在应用费用之前删除吗?

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
4

2 回答 2

0

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

当我将 Batch Size 设置为 100kb 时,我的客户端 Synchronize 抛出DirectoryNotFoundException,通常我运行 500kb。我只在大型同步(例如大型数据库的初始同步)上看到了这一点。随后的同步工作得很好,因为较小)。

更新

根据MS 文档,问题可能是由超过MemoryDataCacheSize 110% 的数据库行引起的。

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

于 2014-05-14T14:11:25.887 回答
0

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

如果定义了多个范围(并且范围足够大以使用批处理),也可能发生此“找不到路径的一部分”问题,因为 MS 的示例代码中有一个小错误。问题出在 SqlWebSyncService 中的 Dispose 上,删除了此会话的批处理文件夹,但目录信息变量未设置为 null(这是下一个范围用于了解它是否正在创建文件夹的测试)。添加将批处理目录设置为 null 可以解决此问题,因为当 CheckAndCreateBatchingDirectory 然后运行它时,它会发现批处理目录为 null 并完成它。

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,发现问题消失了。事后看来,这是因为第一个范围都适合一个批次,所以它没有被分解并实施批处理。当我们将大小设置为较小时,我们的第一个作用域(3 个中的第一个)将使用批处理,当作用域 2 启动时我们会看到这一点。

于 2016-07-26T20:30:06.977 回答