在表上存在外键,并发插入数据的情况下产生死锁,求解

Tiantian8899 2014-07-02 11:15:52

-- 建表Audit,ID为主键子增
CREATE TABLE [dbo].[Audit](
[ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[TypeName] [varchar](50) NOT NULL
)
GO
-- 建表AuditFiedl, ID为主键自增
CREATE TABLE [dbo].[AuditField](
[ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[AuditID] [int] NOT NULL,
[Field1] [varchar](50) NOT NULL
)

GO
-- 表AuditField AuditID字段设置为外键,引用Audit表的ID字段
ALTER TABLE [dbo].[AuditField]
ADD CONSTRAINT [FK_AuditFiled_Audit] FOREIGN KEY([AuditID])
REFERENCES [dbo].[Audit] ([ID])
GO


接下来造一些测试数据向两张表里插入数据:

DECLARE @audit TABLE
(
ID int not null,
TypeName varchar(50)
)

DECLARE @auditField TABLE
(
AuditID int not null,
Field1 varchar(50)
)

-- ADD TEST DATA
DECLARE @i int = 1
DECLARE @rowCount int = 500
WHILE @i<=@rowCount
BEGIN
INSERT INTO @audit
VALUES(@i, 'SomeTypeName')

INSERT INTO @auditField
(AuditID,Field1)
VALUES(@i,'SomeThing')

SET @i += 1
END


想两张表里插入数据:
begin transaction
INSERT INTO dbo.Audit
SELECT TypeName
FROM @audit
ORDER BY ID

declare @lastIdentity int = @@identity
declare @offSet int = @lastIdentity - @rowCount

INSERT INTO dbo.AuditField
SELECT AuditID+@offSet AS AuditID, Field1
FROM @auditField
ORDER BY AuditID
commit transaction



在以上向两张表中插入数据的事物并发执行时发生死锁,貌似是因为外键引起的,但又分析不出为什么会导致死锁。
执行插入操作过程中,其中一个进程得到一个错误:
Msg 547, Level 16, State 0, Line 40
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_AuditFiled_Audit". The conflict occurred in database "MyDB", table "dbo.Audit", column 'ID'.
但想不通为什么会有这个错误。说明一下,在Audit表上没有触发器什么的。另一个进程被强制干掉,被请大神帮忙分析一下,急求答案。
...全文
288 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
KevinLiu 2014-07-03
  • 打赏
  • 举报
回复
这个跟死锁有什么关系,就算违反了约束啊,先看看什么是约束吧。
發糞塗牆 2014-07-03
  • 打赏
  • 举报
回复
这报错信息完全跟死锁沾不上半点关系啊,只是你违反了外键约束而已。不过的确,外键有可能导致死锁,特别是外键上没有索引的时候。
guostong 2014-07-03
  • 打赏
  • 举报
回复
begin transaction INSERT INTO dbo.Audit -- 并发时, transaction 中的 identity 不能保证连续 SELECT TypeName FROM @audit ORDER BY ID declare @lastIdentity int = @@identity declare @offSet int = @lastIdentity - @rowCount INSERT INTO dbo.AuditField SELECT AuditID+@offSet AS AuditID, Field1 -- auditid 是连续的, 会导致conflicted with the FOREIGN KEY FROM @auditField ORDER BY AuditID commit transaction

22,299

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧