2012-06-29 8 views
1

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

Я использую SQL Server 2008 R2, выполняющий вставки T-SQL и после запуска триггера.

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

Использование уровней изоляции вызывает взаимоблокировки или просто НЕ решить проблему.

Процедура Я использую ответ/решение от Фила SQL Server dependent Identity - is there such a thing?

Проблема заключается в том:

иногда вставки получить между предыдущей вставкой и его после того, как триггер вставки, в результате чего этот результат :

RoomID ItemID ItemDescription ID 
------ ------ --------------- -- 
7  1  Door    1 
7  2  Window (West) 2 
7  3  Window (North) 3 
8  1  Door    4 
8  2  Table #1   5 
8  3  Table #2   6 
7  4  Table #1   7 
8  4  Chair #1   8 
7  6  Table #2   9 
7  5  Table #3  10 
8  5  Chair #2  11 

См. ID # 9 и № 10. Идентификаторы Thair Item переключаются. ItemID должен был быть 5 и 6 соответственно, а не 6 и 5, но 10-я вставка, вероятно, произошла до того, как триггер после 9-го завершения завершил выполнение.

Эта проблема возникает менее 0,5% вставок: 2 переключателя с 4 записями для 1000 вставок или менее. Да, иногда нет появления переключателей.

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

Снижение уровня изоляции уменьшает количество переключателей, но они все еще созданы.

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

Кто-нибудь видит выход?

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

+1

Непонятно мне, что ItemID есть или делает. Можете ли вы использовать вычисляемый столбец, чтобы найти его вместо триггера 'after'? –

+0

Кроме того, в SQL 2012 вы можете использовать последовательность. –

+0

Можете ли вы показать нам ... '1 таблицу перед вставками. '2' вставки thmeselves, и их порядок. '3' код в триггере. – MatBailie

ответ

5

Как насчет использования instead of insert trigger?

Конечно, вам нужно будет сделать фактическую вставку самостоятельно, но это поддерживается поведение в SQL Server. Нет перед вставками триггеров или что-то подобное.

В любом случае, вы все равно можете использовать свою текущую логику обработки триггера в этом типе.

Чтобы попытаться представить лучшее решение, можете ли вы объяснить, что вы пытаетесь сделать? Вставка нескольких потоков в эту таблицу? Это процесс в режиме реального времени?

Это аукцион подобный. Да, в эту таблицу вставляются несколько потоков. Проблема задняя, ​​но бывает.Пока нет причин для жалоб, но может быть (коммутаторы произошли к тому моменту, когда не на критическом очках). Пользователи, которые инициируют вставки, должны знать, каков их приоритет в списке заказов. ItemID используется почти сразу, поэтому не может рассчитываться «на лету» (с подсчетом подсчета (*) ... где ..) позже, когда это необходимо, в миллисекундах. Неверный порядок ItemID может привести к потерям для одного и неправомерного выигрыша для другого.

Ну, многопоточные вставки почти никогда не являются хорошей идеей на SQL-сервере. По крайней мере, не без какой-то синхронизации.

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

Сначала я также использовал 8-16 потоков, чтобы делать свои вставки непосредственно в базе данных. И я точно это заметил: тупики. Поэтому я начинаю думать о том, как я мог бы поставить в очередь эти сообщения, так что только 1 поток (1 соединение) будет вставляться в любое время.

Я закончил эту запись в MSMQ (транзакционном). Некоторые другие процессы поступают и берут их отсюда (также транзакционно) и вставляют их в партии в базе данных. Мои записи гарантированно поступят в правильном порядке, в том, в каком они были отправлены.

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

Это просто идея. Вы также можете рассмотреть Service Broker для очередей, особенно если вы не хотите обрабатывать обработку вне SQL Server.

Кроме того, что-то стоит попробовать - это транзакции с Snapshot Isolation level and row versioning, но я рекомендую идти по пути MSMQ/Service Broker.

+0

Это аукцион подобный. Да, в эту таблицу вставляются несколько потоков. Проблема - задняя, ​​но происходит. Пока нет причин для жалоб, но может быть (переключатели произошли к тому моменту, когда не в критической точке). Пользователи, которые инициируют вставки, должны знать, каков их приоритет в списке заказов.ItemID используется почти сразу, поэтому не может рассчитываться «на лету» (с подсчетом count (*) ... где ..) позже, когда это необходимо, в миллисекундах. Неправильный порядок ItemID может привести к потерям для одного и неправомерного выигрыша для другого. – Different111222

+0

@ Different111222 - Следуйте по ссылке, предоставленной этим ответом. Используйте триггеры 'INSTEAD OF', а не триггеры AFTER. – MatBailie

+0

@ Different111222: Обновленный ответ с альтернативой (два на самом деле). –