Синхронизация основных данных - отслеживание удаленных объектов - PullRequest
6 голосов
/ 26 января 2012

Я настраиваю базовую службу синхронизации для разрабатываемого приложения для iPad.Цель состоит в том, чтобы обеспечить согласованность данных в нескольких экземплярах приложения для iPad, а также иметь версию данных, доступную только для чтения в Интернете, и, следовательно, развернуть специальное решение.

Текущий поток таков:

  • Каждый объект имеет поля «создан», «изменен» и «UUID», которые автоматически обновляются базовыми данными
  • При синхронизации каждый объект с датой создания или изменения после датыдата последней синхронизации сериализуется в JSON и отправляется на сервер
  • . Сервер сохраняет любые изменения в базе данных MySQL, используя сгенерированные клиентом UUID в качестве PK (если есть конфликт, он просто использует последний измененный объект как«истинная» версия, ничего особенного) и отправляет обратно все обновленные сущности клиенту
  • Затем клиент объединяет эти изменения обратно в свою базовую базу данных

Кажется, все этоработать нормальноМоя проблема в том, как отслеживать удаленные объекты, используя этот метод?Я предполагаю, что могу добавить флаг «удален» к каждому объекту и установить его всякий раз, когда клиент что-то удаляет, затем я могу передать это изменение на сервер с остальными данными синхронизации.После завершения синхронизации клиент может фактически удалить эти объекты.Мои вопросы:

  • Могу ли я переопределить методы удаления Core Data для автоматической установки этого флага?
  • Требуется ли для этого сохранение всех удаленных объектов на сервере в течение неопределенного времени?У нас не будет возможности узнать, когда каждый клиент синхронизировал и фактически удалял каждую сущность (я в настоящее время не отслеживаю экземпляры клиентов)
  • Есть ли лучший способ сделать это?

Ответы [ 5 ]

6 голосов
/ 01 февраля 2012

Как насчет таблицы дельта-истории с UUID и созданным / обновленным / удаленным полем, возможно, с номером редакции для каждого обновления? Таким образом, вы держите небольшой контрольный список изменений с момента вашей последней успешной синхронизации.

Таким образом, если вы удалите объект, вы можете добавить запись в таблицу истории дельты с удаленным UUID и отметить ее как удаленную. То же самое с созданными и обновленными объектами, вам нужно только проверить дельта-таблицу, чтобы увидеть, какие элементы вам необходимо удалить, обновить, создать и т. Д. На сервере. Вы можете даже хранить каждую ревизию на сервере, чтобы поддерживать откат к предыдущей версии будущее, если тебе так хочется.

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

Вы можете использовать NSManagedObjectContext методы selectedObjects, updatedObjects, deleObjects для создания дельта-объектов перед каждой процедурой сохранения:)

Мои 2 цента

1 голос
/ 08 января 2014

Вы можете взглянуть на Кроссплатформенная синхронизация данных Дэна Гровера , если вы этого не сделали.Это очень хорошо написанная статья о синхронизации и iOS.

О ваших вопросах:

  1. Вы можете избежать удаления файла в Core Data и установить «флаг удаления»:просто обновите файл вместо того, чтобы удалить его.Вы можете создать свой собственный метод «удаления», который на самом деле будет вызывать и обновлять флаг в записи.

  2. Всегда сохранять last_sync и last_updated для каждой записи на сервере и на каждом клиенте,Таким образом, вы всегда будете знать, когда кто-то что-то изменил, и было ли это изменение синхронизировано или нет с «базой данных правды».

  3. Отслеживать удаленные файлы очень сложноЯ думаю, что лучший способ сделать это - отслеживать историю синхронизаций для каждой таблицы, но это трудная задача.Самый простой способ, используя этот тип конфигурации «база данных правды», - пометить файлы, так что да, вы должны хранить данные как на сервере, так и на клиенте.

1 голос
/ 07 февраля 2012

Требуется ли хранить удаленные объекты на сервере или нет, зависит от ваших потребностей.Вам понадобится удаленный флаг, чтобы пометить его как удаленный для синхронизации, возможно, также на сервере, в зависимости от вашего желания выполнить откат.

Я позаботился об этой проблеме несколькими способами ранее.Вот одна из возможностей:

Когда клиент удаляет что-либо, просто отметьте его для локального удаления и удаления с сервера во время синхронизации (в этот момент вы можете очистить основные данные).Когда другие клиенты запрашивают доступ к этим данным, отправьте обратно HTTP 404, потому что у вас больше нет объекта.В этот момент клиент может удалить объект локально.Теперь, если клиент запрашивает список вещей, и этот объект был удален, он просто будет отсутствовать в списке вещей, которые он возвращает, так что вы можете обнаружить это и удалить его.Я делаю это на клиенте, создавая массив идентификаторов объектов при получении ответа от сервера и удаляя все локальные объекты, у которых нет этих идентификаторов.

У нас есть удаленное поле на сервере, нопросто чтобы иметь возможность откатить на случай, если что-то будет случайно удалено.

Конечно, вы можете вернуть удаленные объекты клиенту, чтобы они знали об удалении, но если вы не хотите сохранять копию насервер, вы должны сделать некоторое предположение, что все клиенты будут обновляться в течение определенного периода времени.Тогда вы можете собрать мусор после истечения этого периода времени.

Мне не очень нравится это решение.Если ваши данные слишком тяжелые, чтобы запрашивать все объекты для полной синхронизации, вы можете использовать свою текущую стратегию слияния для создания и обновления, а затем выполнить отдельный вызов для проверки удаленных элементов.Этот вызов может просто запросить все идентификаторы, которые клиент должен иметь на устройстве.Это может удалить те, которые не существуют.ИЛИ он может отправить все идентификаторы на клиенте и получить список идентификаторов для удаления.

Я думаю, что вам нужно предоставить более подробную информацию о характере данных, если вы хотите более взвешенное предложение.

1 голос
/ 02 февраля 2012

Относительно вашего второго вопроса: вы можете спроектировать это так, чтобы на сервере не приходилось хранить удаленные записи, если хотите. Сообщите каждому приложению, хранится ли на сервере данный фрагмент данных (на основе его UUID) (например, добавьте свойство existOnServer или подобное). При запуске создается новый элемент false в приложении, но устанавливается значение true после первой синхронизации с сервером. Таким образом, если приложение пытается выполнить синхронизацию позже, но UUID не найден, вы можете различить два случая: Если существует значение falseOnServer, то этот элемент создается заново и должен быть синхронизирован с сервером, но если он равен true тогда это может означать, что он уже был на сервере раньше, но теперь был удален, поэтому вы можете удалить его и в приложении.

Я бы, вероятно, возразил против этого подхода, так как он кажется мне более подверженным ошибкам (я представляю, что ошибка базы данных или соединения неправильно интерпретируется как удаление), и хранение записей на вашем сервере обычно не было бы большой проблемой но это возможно. «Дельта-подход», предложенный dzeikei, может использоваться одновременно, поэтому обновление записи, которая не существует на сервере, означает, что она была удалена, а вставка - нет.

0 голосов
/ 23 февраля 2016

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

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...