2016-11-18 1 views
0

Я отправляю запрос для некоторого сервиса и возвращаю результат. Я хочу знать, получил ли я в прошлом тот же «ответ». Итак, я планирую использовать Azure Table в качестве механизма кэширования.Таблица хранения Azure - Вставьте пакет строки и проверьте, существуют ли они

я сделать эти небольшие ДОУ:

TableBatchOperation batchOperation = new TableBatchOperation(); 
CachedUrl customer1 = new CachedUrl(Guid.Empty, "test1"); 
CachedUrl customer2 = new CachedUrl(Guid.Empty, "test2"); 
batchOperation.Insert(customer1); 
batchOperation.Insert(customer2); 
table.ExecuteBatch(batchOperation); 

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

Проблема во втором запуске. Когда я выполняю этот код:

TableBatchOperation batchOperation = new TableBatchOperation(); 
CachedUrl customer1 = new CachedUrl(Guid.Empty, "test1"); 
CachedUrl customer2 = new CachedUrl(Guid.Empty, "test2"); 
CachedUrl customer3 = new CachedUrl(Guid.Empty, "test3"); 
batchOperation.Insert(customer1); 
batchOperation.Insert(customer2); 
batchOperation.Insert(customer3); 
table.ExecuteBatch(batchOperation); 

(Примечание к оных из customer3)

Что я ожидал получить это сообщение, говорят:

  • customer1 - существует
  • покупатель2 - есть
  • customer3 - добавил

То, что я на самом деле получаю это исключение (по методу ExecuteBatch()):

Запрос информации RequestID: 5116ee8a-0002-0024-7ac1-415787000000 RequestDate: Пт, 18 ноя 2016 17:33:08 GMT StatusMessage: 0: Объект уже существует. ErrorCode: EntityAlreadyExists

Сервер обнаружил, что объект №1 существует, поэтому пропустите всю задачу.

Как я могу получить ожидаемый ответ?

Наивное решение состоит в том, чтобы попробовать добавить все N элементов, один за другим. Но это решение является самым медленным (N HTTP-запросов вместо 1 запроса).

ответ

0

Ожидаемое поведение. Вся партия выходит из строя, как только любой объект в этой партии выходит из строя.

Один из возможных вариантов использования - InsertOrReplace - вместо Insert. Это обновит объект, если он существует, иначе вставляет объект.

От documentation:

Добавляет TableOperation к TableBatchOperation, который вставляет указанный объект в таблицу, если объект не существует; если объект существует, то его содержимое заменяется предоставленным объектом .

+0

Как с помощью 'InsertOrReplace' может решить мою проблему? Таким образом, я не могу знать после выполнения команды, если этот элемент был добавлен или просто заменен ... – No1Lives4Ever

+0

Я не верю, что есть способ узнать, были ли сущности заменены или просто были добавлены. Возможно, хранение таблиц не очень подходит для того, что вы пытаетесь сделать. Рассматривали ли вы другие варианты? –

2

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

Хранение исключений возвращает фактический индекс неудачной операции из партии и ошибки, связанной с этим.

В вашем примере ниже индекса несостоявшейся операции 0 и ошибка EntityAlreadyExists:

: Указанный объект уже существует. ErrorCode: EntityAlreadyExists

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

См лазурного хранения Exception анализатор, который я реализовал в NuGet, извлекающий индекс провалившейся операции и другой полезной информации, как HttpStatusCode от объекта StorageException для вас: https://www.nuget.org/packages/AzureStorageExceptionParser/

Для того, чтобы избежать многократных назад и вперед звонков на лазурь при каждой неудачной операции, вот альтернативное решение, которое вы можете изучить:

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

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

Вы можете комбинировать этот подход с первого подхода (повторных попыток), чтобы иметь более надежное решение

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