【发布时间】:2012-02-03 20:48:29
【问题描述】:
在 sql server 2008 中调用我的存储过程时遇到了死锁问题。一个 xml 字符串通过 biztalk 传递到存储过程中,并且可以快速连续调用多次。我遇到的问题是,如果该过程被快速连续调用 5 次,则前 4 个调用将回滚,最后一个调用由于死锁而提交给数据库。下面是该过程的代码 - 它使用 OPENXML 解析 xml 字符串并插入表 A。然后我从表 A 中获取新的唯一标识符并将多个子记录插入表 B。有关如何解决此问题的任何指导都会不胜感激。
错误消息: System.Data.SqlClient.SqlException (0x80131904):事务(进程 ID XX)在锁资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务。
表格详情
表A
- Id int identity(1,1) 主键,
- ColumnA varchar(15) 不为空,
- ColumnB varchar(20) 不为空,
- 添加了DateTime 日期时间默认(getdate())
表B
- Id int identity(1,1) 主键,
- TableAId int 不为空,(FK)
- ColumnC varchar(30) 不为空
XML
<Transactions>
<Transaction>
<ColumnA>Column A Value</ColumnA>
<ColumnB>Column B Value</ColumnB>
<ChildItems>
<ChildItem>
<ColumnC>Column C Value</ColumnC>
</ChildItem>
<ChildItem>
<ColumnC>Another Column C Value</ColumnC>
</ChildItem>
<ChildItem>
<ColumnC>Yet Another Column C Value</ColumnC>
</ChildItem>
</ChildItems>
存储过程
CREATE PROCEDURE [dbo].[proc_ProcessXml]
(
@ResponseXml varchar(max)
)
WITH EXECUTE AS CALLER
AS
BEGIN TRANSACTION
DECLARE @xmlHandle int
declare @tableAId int
EXEC sp_xml_preparedocument @xmlHandle OUTPUT, @ResponseXml,
INSERT INTO TableA
(
ColumnA,
ColumnB
)
SELECT columnA, columnB
FROM OPENXML(@xmlHandle, '/Transactions/Transaction', 1)
WITH(
columnA varchar(15) 'ColumnA',
columnB varchar(20) 'ColumnB'
)
select @tableAId = SCOPE_IDENTITY()
INSERT INTO TableB
(
TableAId,
ColumnC
)
SELECT @tableAId, columnC
FROM OPENXML(@xmlHandle, '/Transactions/Transaction/ChildItems/ChildItem', 1)
WITH(
columnC varchar(30) 'ColumnC',
)
EXEC sp_xml_removedocument @xmlHandle
IF @@ERROR <> 0
BEGIN
ROLLBACK
END
ELSE
BEGIN
COMMIT
END
【问题讨论】:
-
您是否尝试过更严格的隔离级别?
-
顺便说一句,这似乎是过程长度与事务相结合的副作用。这是否需要事务,即您的选择使用必须未被其他可能并发操作修改的数据来创建您的插入?
标签: sql-server biztalk deadlock sql-server-openxml