2013-09-30 3 views
1

Привет представьте у меня есть такой код:как сделка с атомарности ситуации

0. void someFunction() 
1. { 
2. ... 
3. if(x>5) 
4. doSmth(); 
5. 
6. writeDataToCard(handle, data1); 
7. 
8. writeDataToCard(handle, data2); 
9. 
10. incrementDataOnCard(handle, data); 
11. } 

Вещь следующее. Если выполняется этап 6 & 8, а затем кто-то говорит, что он удаляет карту - тогда операция 10 не будет выполнена успешно. Но это будет ошибкой в ​​моей системе. Значение, если выполнены 6 & 8, также должно быть выполнено 10. Как бороться с такими ситуациями?

Краткое описание: Что я хочу сказать, после шага 8 кто-то может удалить мою физическую карту, а это значит, что шаг 10 никогда не будет достигнут, и это вызовет проблему в моей системе. А именно, карта будет инициализирована неполными данными.

+2

Предпочтительно, чтобы вы писались на карточку только один раз, как часть одной транзакции. – moswald

+1

Не выполняйте действия 6 и 8, если у вас нет гарантии, что карта не будет удалена. –

+1

Используйте try/catch, чтобы остановить исключение из-за сбоя вашего приложения? Попросите функцию 'incrementDataOnCard()' проверить, существует ли карта? Сколько времени займет запись - можете ли вы выполнить их внутри одной транзакции, которая зависит от флага, который контролирует «состояние карты»? – newfurniturey

ответ

2

Вы должны создать своего рода Protcol, например, вы пишете на карту список operatons для завершения:

  1. step6, Step8, Step10

и, как вы заполните задачи, которые вы удаляете из списка.

Когда вы перечитываете данные с диска, вы проверяете список, если какая-либо запись остается. Если это так, операция не завершилась успешно, и вы восстановите предыдущее состояние.

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

+0

Я не совсем согласен с последним частично, вы можете сделать некоторую копию при записи и другие методы, чтобы фактически сохранить старые данные и просто «зафиксировать» в конце. Если вы не совершаете, старые данные все еще используются, тогда на вашей карте не будет проблемы согласованности. – Geoffroy

+0

@Geoffroy. Когда вы пишете новый коммит, все еще может быть выброс. Вам все равно понадобится способ показать, что фиксация выполнена успешно. Если вы не можете гарантировать, что атомный напишет, все другие методы не удастся. – RedX

+0

@RedX: Как узнать, что было в предыдущем состоянии? Это означает, что я должен хранить текущее состояние всегда где-то в другом месте (на карте)? –

2

Если транзакция прервана, карта находится в состоянии сбоя. У вас есть три варианта:

  1. Ничего не делать. Карта находится в состоянии сбоя, и она останется там. Советуйте пользователям не играть с карточкой. Карточка может иметь право на полную очистку или форматирование.
  2. Откат транзакции при следующей загрузке карты. Для выполнения отката вам потребуется достаточно информации о карте и/или каком-то центральном репозитории.
  3. Завершите транзакцию в следующий раз, когда карта станет доступной. Для выполнения завершения вам потребуется достаточно информации на карте и/или в каком-либо центральном хранилище.

Во всех трех случаях вам необходимо иметь флаг на карте, обозначающий транзакцию.

0

Для получения более подробной информации требуется более подробная информация.

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

  1. Для каждой записи написанной, поддерживать другой элемент данных (на карточке) который указывает состояние записи. Это состояние будет инициализировано чем-то (например, «ЗАПИСЬ») перед выполнением операции writeData.Затем это состояние устанавливается на «WRITTEN» после выполнения операции incrementData (успешно!). При чтении с карты - вы сначала проверяете это состояние и игнорируете (или удаляете) запись, если ее не ПИСЬЕТ.

  2. Другим вариантом является поддержание двух (постоянных) счетчиков на карте: один подсчет количества записей, которые начали писать, а другой подсчитывает количество записей, которые закончились письмом. Вы увеличиваете первое значение перед выполнением записи, а затем увеличиваете второе после (успешно) выполнение вызова incrementData. Когда вы позже читаете с карты, вы можете легко проверить, действительно ли запись действительно действительна или ее нужно отменить. Эта опция действительна, если письменные записи упорядочены или проиндексированы так, чтобы вы могли видеть, сколько и сколько записей действительно, просто проверив счетчик. Это имеет преимущество, так как только два счетчика для любого количества записей (по сравнению с 1 состояния для каждой записи в варианте 1.)

на хосте (программное обеспечение) стороны Затем нужно проверить, что карта доступный до начала записи (не пишите, если его там нет). Если после операции incrementData вы обнаружите, что карта была удалена, вы должны быть уверены в том, что будете убирать вещи (удалять незавершенные записи, обновлять счетчики) либо после того, как обнаружите, что карта снова вставлена, либо перед другой записью. Для этого вам необходимо сохранить информацию о состоянии со стороны программного обеспечения.

Опять же, тип решения (из многих других) зависит от конкретной системы и требований.

0

Разве это не просто:

  • Копирование данных в temporary_data.
  • Напишите временные_данные.
  • Увеличение временных_данных.
  • Переименовать данные в old_data.
  • Переименовать временные_данные в данные.
  • Удалить старые_данные.

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

0

Вы не сказали, что вы увеличиваете (или почему), или как ваши данные структурированы (предположительно, существует некоторая взаимосвязь между тем, что вы пишете с помощью writeDataToCard и тем, что вы увеличиваете).

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

  1. самое простое, что могло бы работать - полной карты совершить или-Откат

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

    Запишите свои новые данные в грязную область, и, когда это будет сделано, обновите индексный байт (так что обмен чистым & грязным).

    Либо индекс обновляется, либо ваши новые данные хороши, либо карта вытаскивается, а предыдущая чистая копия по-прежнему активна.

    Pro - это очень просто

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

  2. ... теперь меньше места ... - фиксации или отката-меньшие подмножества

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

    Pro - все еще довольно простой

    Con - вы не можете обрабатывать зависимости между кусками, они должны быть изолированы

  3. журналирующих

    В соответствии с ответом RedX, в это используется множеством файловых систем для обеспечения целостности.

    Pro - это твердый метод, и вы можете найти документацию и примеры реализации существующих файловых систем

    Con - вы просто написали современную файловую систему. Это действительно то, что вы хотели?

+0

см. Мой обновленный вопрос с более подробной информацией: http://stackoverflow.com/questions/19099937/writing-of-data-interrupted-by-some-event/19100024?noredirect=1#19100024 –

Смежные вопросы