【问题标题】:Deadlock MS-SQL when Inserting Into a Table插入表时死锁 MS-SQL
【发布时间】:2019-04-19 19:41:53
【问题描述】:

我正在使用以下查询来插入给定表发生的相应历史表更改。我正在对 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) 

我从 system_health 获得了这个样本

【问题讨论】:

  • 检查 system_health 跟踪文件目标以获取死锁事件详细信息。
  • 使用相同的变量名不会导致死锁。插入时是否有其他进程访问此数据库?
  • 有其他进程同时引用同一个数据库上的sys.all_columns @PiotrS
  • 我使用了 10 个线程,因此我最多可以有 9 个其他进程访问数据库,同时插入正在执行它们自己的插入到其他历史表中

标签: sql-server python-3.x multithreading deadlock


【解决方案1】:

似乎某个并发进程正在同时更改或创建表。死锁 XML 应该包含有关正在发生的事情的其他详细信息。

但无论实际原因是什么,解决方法都很简单。使用上面的脚本在静态 SQL 中生成触发器主体,这样您就不必为每个插入查询目录。

在您的数据库中创建一个名为admin.GenerateHistoryTables 和一个名为admin.GenerateHistoryTriggers 的过程,并提前运行这些过程以安装历史表并连接触发器。

或者停止重新发明轮子并使用Change Data CaptureTemporal Tables

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    相关资源
    最近更新 更多