2013-11-21 4 views
1

В моей многопоточной программе один поток отбрасывает индексы в таблице (это происходит сначала), а другие потоки вставляют записи в одну и ту же таблицу. Случилось так, что при попытке сброса индекса таблица блокируется, а транзакции вставки становятся «Ожидание».Зачем нужно индексировать падение?

После того, как вы потратили много времени на не-решения проблемы, я нашел реальное решение: совершить сразу после сброса индекса. Когда выдается commit, таблица разблокирована и транзакции вставки завершаются успешно.

Мой вопрос: Почему? У меня создалось впечатление, что индекс Drop - это заявление DDL и поэтому его не нужно делать. Кажется, Postgres доказывает, что я ошибаюсь.

+0

Если вам нужно выпустить COMMIT после удаления индекса, то какой инструмент вы используете использование для подключения к db открывает транзакцию. Вы используете JDBC? Я считаю, что есть переключатель для режима autocommit. 'DROP INDEX' должен вынуть эксклюзивную блокировку достаточно долго, чтобы выполнить команду, и определить, что никакие другие транзакции не используют индекс (в противном случае у вас могли бы быть непоследовательные или неправильные результаты). – bma

+0

Вы правы, это было связано с открытием транзакции. Пришлось совершить. – ADTC

ответ

2

Я не знаю о Postgres, но заявления DDL не всегда автоматические. В Oracle, например, они есть, но в DB2 они не являются (вы можете сделать создать таблицу + индексов, а затем откат всей партии). Я думаю, что SQL Server также нуждается в фиксации (если не включена автоматическая фиксация).

В основном (в зависимости от аромата БД) заявление DDL не всегда выполняется автоматически.

+1

Режим фиксации определяется приложением, к которому вы подключаетесь, и DDL неявно фиксируется в большинстве инструментов. Риск звукового педантизма - это «Postgres» или «PostgreSQL», а не «postgress». – bma

+4

[Transactional DDL в PostgreSQL: конкурентный анализ] (http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis) делает сравнение между различными двигателями относительно транзакционного DDL. –

+1

Мне нравится, как в [статье Википедии о DDL] (http://en.wikipedia.org/wiki/Data_definition_language#CREATE_statements) В качестве примера приводится Postgres. –

3

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

Другие базы данных SQL делают это по-другому.

(Nitpicking: некоторые команды DDL в PostgreSQL не могут выполняться в транзакционном блоке, только в транзакции сами по себе. Таким образом, вы можете считать, что это исключения из вышеупомянутых «всех команд DDL». Но это не совсем то же самое, что и ваш вопрос: эти команды еще нужно зафиксировать, они просто не могут быть запущены в транзакции вместе с другими командами.)

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