Глобальные временные таблицы - блокировка строк + вопрос параллелизма - PullRequest
3 голосов
/ 06 мая 2011

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

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

Как мне это сделать (не допуская перекрытия)?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 06 мая 2011

Если бы в 11g я использовал SELECT ... FOR UPDATE SKIP LOCKED.

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

2 голосов
/ 06 мая 2011

Здесь есть две проблемы, поэтому давайте рассмотрим их по отдельности:

Как разделить некоторую работу между несколькими потоками / сеансами?

Вы можете использовать расширенную очередь или функцию SKIP LOCKED в, предложенный Адамом .

Вы также можете использовать столбец, содержащий информацию об обработке, например столбец STATE, который пуст, когда не обработан.Каждый поток будет начинать работу над строкой с:

UPDATE your_table 
   SET state='P'
 WHERE STATE IS NULL 
   AND rownum = 1
RETURNING id INTO :id;

В этот момент поток выполнит фиксацию для предотвращения блокировки другого потока.Затем вы выполняете свою обработку и выбираете другую строку, когда закончите.

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

Как временные таблицы будут вести себя с несколькими потоками?

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

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

0 голосов
/ 06 мая 2011

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

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

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