Платформа синхронизации — пакетная обработка

Я синхронизирую две удаленные базы данных (Sql Express и Sql Compact), используя структуру синхронизации 2.1 через WCF (N-Tier), используя пакетную обработку.

Недавно я получаю этот файл журнала, это ошибка, которая появляется довольно редко, но когда это происходит, это создает много проблем (кажется, что таблицы из данных, включенных в эту область синхронизации, которая завершается сбоем, удаляются). Я уверен, что никто не возится с 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

person Angela_SB    schedule 07.11.2012    source источник
comment
это правильный каталог пакетной обработки, который вы указали? кажется, что таблицы из данных, включенных в эту область синхронизации, которая завершается сбоем, удаляются - фреймворк никогда не удаляет пользовательские таблицы. ваша ошибка в командном файле. даже если в пакетном файле есть ошибка, последующие синхронизации все равно должны работать.   -  person JuneT    schedule 08.11.2012
comment
Привет, я указал путь к каталогу пакетной обработки. Проблема в том, что при возникновении этой ошибки содержимое таблицы, входящей в область видимости, пусто (удаляется не таблица, а ее содержимое). Я не смог воспроизвести это на своей машине, но это входные данные, которые я получаю из файлов журнала.   -  person Angela_SB    schedule 08.11.2012
comment
вы имеете в виду, что таблица очищается после ошибки, или вы имеете в виду, что синхронизируемая таблица на самом деле пуста?   -  person JuneT    schedule 08.11.2012
comment
Да, для этой области ErpProduct, где происходит ошибка, я загружаю данные только из базы данных SQL EXPRESS в базу данных SQL Compact. Между первым появлением проблемы у меня есть несколько обращений к некоторым продуктам (которые должны существовать) напрямую в базу данных, и ничего не найдено. И что подтверждает мой страх, так это сообщение от SyncOrchestrator: DownloadChanges: Applied - Failed: 122363 - 0   -  person Angela_SB    schedule 08.11.2012
comment
Да, что? структура синхронизации очищает вашу таблицу? или он действительно пустой? Сбой может означать либо конфликт, либо ошибку при применении изменений. подпишитесь на событие ApplyChangeFailed и посмотрите, является ли это ошибкой или конфликтом   -  person JuneT    schedule 08.11.2012
comment
Опустошает стол. Я подписался на событие ApplyChangeFailed, и ошибка не обнаружена.   -  person Angela_SB    schedule 08.11.2012
comment
единственный способ, которым sync fx удалит строки, — это если строки были удалены из источника. afaik, в подготовке или синхронизации нет ничего, что могло бы очистить или очистить таблицу (если вы не используете более старый SQLCEClientSyncProvider). так что событие ApplyChangeFailed вообще не запускается? на какого провайдера вы подписаны? клиент или сервер?   -  person JuneT    schedule 09.11.2012
comment
Я использую SqlCeSyncProvider для клиента и KnowledgeSyncProvider для сервера.   -  person Angela_SB    schedule 09.11.2012


Ответы (2)


Попробуйте изменить SqlSyncProvider.MemoryDataCacheSize (размер пакета) на своем клиенте.

Мой клиент Synchronize выдавал DirectoryNotFoundException, когда я устанавливал размер пакета на 100 КБ, обычно я запускаю 500 КБ. Я видел это только при больших синхронизациях (например, начальная синхронизация большой базы данных). Последующие синхронизации работали нормально, как меньше).

ОБНОВЛЕНИЕ

Согласно документации MS проблема может быть вызвано строкой базы данных, превышающей 110 % от MemoryDataCacheSize.

Приложение указывает размер кэша данных памяти для каждого поставщика, участвующего в сеансе синхронизации. Если оба поставщика указывают размер кэша, Sync Framework использует меньшее значение для обоих поставщиков. Фактический размер кэша будет не более 110% от наименьшего указанного размера. Во время сеанса синхронизации, если размер одной строки превышает 110 % от размера, сеанс завершается с исключением.

person Brent    schedule 14.05.2014

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

Эта проблема «не удалось найти часть пути» также может возникнуть, если определены несколько областей (и области достаточно велики для использования пакетной обработки), поскольку в примере кода из MS есть небольшая ошибка. Проблема заключается в Dispose в SqlWebSyncService, папка пакетной обработки для этого сеанса удалена, но для переменной информации о каталоге не задано значение 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.

person Wes    schedule 26.07.2016