Удаление многих строк без их блокировки

В PostgreSQL у меня есть запрос, подобный следующему, который удаляет 250 тыс. Строк из таблицы строк длиной 1 м:

DELETE FROM table WHERE key = 'needle';

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

DELETE FROM table WHERE key = 'needle' LIMIT 10000;

Этот запрос будет работать хорошо, но, увы, его нет в postgres. заявка впоследствии прекращено, система автоматически перезапускает приложение в фон, если новое событие прибывает. В такой случай, словарь опций перешел к применение: didFinishLaunchingWithOptions: метод вашего приложения делегата содержит ключ UIApplicationLaunchOptionsLocationKey указать, что ваша заявка была запущен из-за события местоположения. После перезапуска вы должны еще настроить объект диспетчера местоположения и вызвать этот метод, чтобы продолжить получение места событий. Когда ты перезапустить службы определения местоположения, текущий событие доставлено вашему делегату немедленно. Кроме того, расположение собственность вашего менеджера Объект заселен наиболее недавнее местоположение объекта еще до вас запускать службы определения местоположения.

Итак, насколько я понимаю, если ваше приложение завершается (и я предполагаю, что если вы не вызовете stopMonitoringSignificantLocationChanges из applicationWillTerminate ), вы проснетесь с Параметр UIApplicationLaunchOptionsLocationKey для приложения : didFinishLaunchingWithOptions . В этот момент вы создаете CLLocationManager , вызываете startMonitoringSignificantLocationChanges и выполняете свою фоновую обработку местоположения в течение ограниченного времени . Так что я в порядке с этим битом.

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

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

Однако параграф Служба значительных изменений в Руководство по программированию осведомленности о местоположении содержит следующее:

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

Это говорит о том, что вы проснулись с данными о местоположении, если ваше приложение было приостановлено, но не упоминает, как вы проснулись:

  • Получает ли UIApplicationDelegate обратный вызов, сообщающий мне, что я возвращаюсь из приостановленного состояния в фоновое состояние?
  • Менеджер местоположения (который был заморожен, когда приложение было приостановлено) начинает получать locationManager: didUpdateToLocation: fromLocation обратные вызовы?
  • Мне просто нужно реализовать код в моем сообщении didUpdateToLocation , которое проверяет состояние приложения и выполняет минимальную обработку в фоновом режиме? 12232 В процессе написания этой статьи, я думаю, что я, возможно, только что ответил на свой вопрос, но было бы здорово, если бы мое понимание этого подтвердилось кем-то более знающим.

109
задан Honey 18 July 2017 в 22:44
поделиться

2 ответа

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

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

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Я пришел к этому выводу с помощью тестового жгута для определения местоположения, который вы можете скачать и опробовать. Это довольно простое приложение, которое позволяет вам включать API значительных изменений и API изменения GPS через пользовательский интерфейс и регистрировать все ответы, которые вы получаете обратно.

N.B. Пункт 6 в предыдущем ответе неверен. Freeze dried приостановленные приложения действительно получают CLLocationManagerDelegate обратные вызовы, когда они пробуждаются из приостановленного состояния.

80
ответ дан 24 November 2019 в 03:25
поделиться

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

  1. Ваше приложение запускается впервые, вы регистрируетесь на startMonitoringSignificantLocationChanges и предоставляете функцию обратного вызова. Пока ваше приложение работает, оно будет вызывать этот обратный вызов всякий раз, когда получает значительное изменение.
  2. Если ваше приложение переведено в фоновый режим, UIApplication получит applicationWillResignActive , за которым следует applicationDidEnterBackground .
  3. Если ваше приложение будет остановлено, когда оно приостановлено в фоновом режиме, вы не получите уведомления; однако, если ваше приложение будет остановлено во время его работы (насколько мне известно, на переднем плане или в фоновом режиме), вы получите момент с помощью applicationWillTerminate . Вы не можете запросить дополнительное фоновое время из этой функции.
  4. Несмотря на то, что ОС была остановлена ​​в фоновом режиме, она перезапустит ваше приложение. Если ваше приложение просто запускается ОС для изменения, вы получите вызов application didFinishLaunchingWithOptions :

     if ([launchOptions objectForKey: UIApplicationLaunchOptionsLocationKey])
    

    поможет вам определить, вернулись ли вы после смены фонового местоположения.

  5. Если вместо этого вы в настоящее время работали в фоновом режиме и ваше приложение вручную перезапускалось пользователем, вы получите applicationWillEnterForeground , за которым следует applicationDidBecomeActive .
  6. Независимо от того, как это произошло, когда ваше приложение перезапускается (если оно все еще не работало в фоновом режиме в результате фоновой задачи и указанная задача начала отслеживать изменения), вам необходимо явно сообщить об этом startMonitoringSignificantLocationChanges снова, потому что обратный вызов больше не прикрепляется после «сублимационной сушки». И да, вам просто нужно реализовать код в didUpdateToLocation после того, как вы повторно подключили какой-либо обработчик местоположения после выхода из приостановленного состояния.

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

О, и если по какой-то случайности вы выпустите приложение, которое делает то, что я хочу, я могу плакать :)

Удачи!

25
ответ дан 24 November 2019 в 03:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: