#sql-server #python-3.x #multithreading #deadlock
#sql-сервер #python-3.x #многопоточность #взаимоблокировка
Вопрос:
Я использую следующий запрос для вставки в соответствующую историческую таблицу изменений, произошедших с данной таблицей. Я выполняю один и тот же запрос одновременно для нескольких таблиц в python (изменяя имя таблицы и базу данных). Ни одна из исторических таблиц не имеет внешних ключей. Но некоторые из казней заканчиваются тупиком. Каждой таблице должна быть присвоена уникальная историческая таблица. Я не уверен, как решить эту проблему. Это потому, что я использую таблицу переменных с одним и тем же именем во всех процедурах?
declare @name_tab table (name_column varchar(200),
dtype varchar(200))
declare @columns varchar(max)
declare @query varchar(max)
declare @database varchar(200)
declare @table_name varchar(200)
set @database = '%s'
set @table_name = '%s'
insert into @name_tab
select c.name as name_column,
t.name as dtype
from sys.all_columns c
INNER JOIN sys.types t
ON t.system_type_id = c.system_type_id
where OBJECT_NAME(c.object_id) = @table_name
set @columns= stuff((select ',' name_column from @name_tab FOR XML PATH('')),1, 1, '')
set @query= 'insert into ' @database '..' 'HISTORY_' @table_name ' select super_q.* from'
'(select cast (GETDATE() as smalldatetime) as TIME_MODIFIED, new_info.* from '
'(SELECT ' @columns ' From ' @database '..' @table_name
' except '
'SELECT ' @columns ' From ' @database '..' 'HISTORY_' @table_name ') new_info) as super_q'
execute(@query)
Комментарии:
1. Проверьте целевой файл трассировки system_health для получения сведений о событии взаимоблокировки .
2. Использование того же имени переменной не приведет к взаимоблокировке. Существуют ли какие-либо другие процессы, которые подключаются к этой БД во время вставки?
3. Одновременно существуют другие процессы, ссылающиеся на sys.all_columns в той же базе данных @PiotrS
4. Я использовал 10 потоков, поэтому у меня могло быть до 9 других процессов, обращающихся к БД во время выполнения вставки, для выполнения их собственной вставки в другие исторические таблицы
Ответ №1:
Похоже, что какой-то параллельный процесс одновременно изменяет или создает таблицу. Взаимоблокировка XML должна содержать дополнительные сведения о том, что происходит.
Но какой бы ни была фактическая причина, решение простое. Используйте приведенный выше сценарий для создания тел триггеров в статическом SQL, чтобы вам не приходилось запрашивать каталог для каждой вставки.
Создайте в своей базе данных процедуру, вызываемую, скажем, admin.GenerateHistoryTables
и вызываемую admin.GenerateHistoryTriggers
, и запустите их заранее, чтобы установить таблицы истории и подключить триггеры.
Или прекратите изобретать колесо и используйте сбор данных изменений или временные таблицы.