我的程序spUmowyXMLintoLOG看起来像:
CREATE PROCEDURE dbo.spUmowyXMLintoLOG
(
@inXML XML,
@PROCID INT,
@idRekorduZrodlowego INT,
@idTabeliZrodlowej INT,
@TrybWywolania INT, /* 0 pierwszy wpis z inXML,
1 drugi wpis z outXML,
-1 czytanie z logu po nazwie obiektu idRekorduZrodloweho i idTabeliZrodlowej */
@outIdWpisuDoLogu INT OUTPUT,
@dataOd DATETIME,
@dataDo DATETIME,
@CzyBlad BIT,
@ErrorMessage VARCHAR(4000),
@uidOperacji VARCHAR(255) = NULL /* UM2-4818 */
)
AS
BEGIN
DECLARE @komunikatPrint VARCHAR(1000)
DECLARE @NazwaObiektu VARCHAR(255)
SELECT @NazwaObiektu = name
FROM dbo.sysobjects WITH(NOLOCK)
WHERE id = @PROCID
BEGIN TRY
IF @TrybWywolania = 0
BEGIN
INSERT INTO dbo.UmowyXMLzInterfejsow_log2(ProcID,NazwaObiektu,inXml,CzyBlad,UIDOperacji)
SELECT @PROCID,@NazwaObiektu,@inXML,@CzyBlad,@uidOperacji
SELECT @outIdWpisuDoLogu = SCOPE_IDENTITY()
/* zamapowanie szczegółów */
INSERT INTO UmowyXMLzInterfejsow_log2_szczegoly WITH(XLOCK,ROWLOCK)
SELECT @outIdWpisuDoLogu,idRekorduZrodlowego,idTabeliZrodlowej
FROM #UmowyXMLzInterfejsow_log_szczegoly WITH(NOLOCK)
/* UM2-4842 BEGIN zapis uida biznesowego */
IF OBJECT_ID('tempdb..#umowyXMLzInterfejsow_log_UIDbiznesowy') IS NOT NULL
BEGIN
INSERT INTO dbo.UmowyXMLzInterfejsow_log2_UIDbiznesowy (idWpisuDoLogu,UIDBiznesowy)
SELECT @outIdWpisuDoLogu,UIDBiznesowy
FROM #umowyXMLzInterfejsow_log_UIDbiznesowy
END
/* UM2-4842 END zapis uida biznesowego */
END
ELSE
IF @TrybWywolania = 1
BEGIN
UPDATE dbo.UmowyXMLzInterfejsow_log2 WITH(XLOCK,ROWLOCK)
SET outXml = @inXML,
DataAktualizacji = GETDATE(),
CzyBlad = @CzyBlad,
ErrorMessage = @ErrorMessage
WHERE idWpisuDoLogu = @outIdWpisuDoLogu
END
ELSE
IF @TrybWywolania = -1
BEGIN
IF ISNULL(@PROCID,0) <> 0
AND ISNULL(@idRekorduZrodlowego,0) <> 0
AND ISNULL(@idTabeliZrodlowej,0) <> 0
BEGIN
SELECT 'Wyszukianie po idRekorduZrodlowego,idTabeliZrodlowej -> dbo.UmowyXMLzInterfejsow_log',l.*,'_szczegoly',ls.*,'SWUIM_SystemyTabeleZrodlowe',stz.*
FROM dbo.UmowyXMLzInterfejsow_log2 l WITH(NOLOCK)
JOIN UmowyXMLzInterfejsow_log2_szczegoly ls WITH(NOLOCK)
ON l.idWpisuDoLogu = ls.idWpisuDoLogu
LEFT JOIN SWUIM_SystemyTabeleZrodlowe stz WITH(NOLOCK)
ON ls.idTabeliZrodlowej = stz.id
WHERE ls.idRekorduZrodlowego = @idRekorduZrodlowego
AND ls.idTabeliZrodlowej = @idTabeliZrodlowej
END
END
IF @TrybWywolania = -2
BEGIN
IF ISNULL(@PROCID,0) <> 0
AND ISNULL(@dataOd,'9999-12-31') <= CONVERT(VARCHAR(10),GETDATE(),120)
AND ISNULL(@dataDo,'9999-12-31') >= CONVERT(VARCHAR(10),GETDATE(),120)
BEGIN
SELECT 'Wyszukianie po dacieWpisu -> dbo.UmowyXMLzInterfejsow_log',l.*,'_szczegoly',ls.*,'SWUIM_SystemyTabeleZrodlowe',stz.*
FROM dbo.UmowyXMLzInterfejsow_log2 l WITH(NOLOCK)
JOIN UmowyXMLzInterfejsow_log2_szczegoly ls WITH(NOLOCK)
ON l.idWpisuDoLogu = ls.idWpisuDoLogu
LEFT JOIN SWUIM_SystemyTabeleZrodlowe stz WITH(NOLOCK)
ON ls.idTabeliZrodlowej = stz.id
WHERE l.NazwaObiektu = @NazwaObiektu
AND l.DataWpisu >= @dataOd
AND l.DataWpisu <= @dataDo
END
END
END TRY
BEGIN CATCH
SELECT @komunikatPrint = 'Wystapił problem z zapisem do XML do logu: ' + ERROR_MESSAGE()
END CATCH
END
如您所见,此过程插入:
INSERT INTO dbo.UmowyXMLzInterfejsow_log2(ProcID,NazwaObiektu,inXml,CzyBlad,UIDOperacji)
SELECT @PROCID,@NazwaObiektu,@inXML,@CzyBlad,@uidOperacji
现在我尝试在执行此过程进行测试时陷入僵局。
我打开 2 个查询窗口,在第一个窗口中我尝试像这样锁定表:
BEGIN TRY
begin tran az
select top 10 * from UmowyXMLzInterfejsow_log2 with(tablockx)
WAITFOR DELAY '00:0:30'
commit tran az
END TRY
BEGIN CATCH
rollback tran az
END CATCH
第二个窗口只是执行此过程 - 插入数据时出现死锁
begin tran az
DECLARE @outIdWpisuDoLogu INT
IF OBJECT_ID('tempdb..#umowyXMLzInterfejsow_log_szczegoly') IS NOT NULL
DROP TABLE #umowyXMLzInterfejsow_log_szczegoly
CREATE TABLE #umowyXMLzInterfejsow_log_szczegoly
(
idWpisuDoLogu [int] NULL,
idRekorduZrodlowego [int] NOT NULL,
idTabeliZrodlowej [int] NOT NULL
)
EXEC dbo.spUmowyXMLintoLOG 'xx',@@procid,null,null,0,@outIdWpisuDoLogu OUTPUT,NULL,NULL,0,NULL
select @outIdWpisuDoLogu
rollback tran az
当我锁定表后 - 程序只执行 30 秒然后输出就没有问题了。
当我将延迟时间更改为 10 分钟时,它只执行 10 分钟......我怎么能在这里陷入僵局?- 它应该出现,因为表被另一个事务锁定。