我有一個.Net應用程序用於表單處理,它可以跨三個不同的SQL Server 2012數據庫刪除/更新/插入數據。當應用程序運行時,它會爲每個需要處理的表單打開一個數據上下文,然後在該上下文中創建一個事務(每分鐘運行一次,因此一次只能有一個表單)。一堆東西發生在這個事務中 - 包括多個存儲的proc調用。SQL-服務器事務阻止神祕
所以這裏的問題:
我們已經設置了什麼,我告訴服務器是完全相同的規格(雖然我懷疑:))。一個用於開發工作;另一個用於客戶端測試。在我們的開發環境中,處理過程毫無問題;但在客戶端測試網站上,它每次都會掛起。我正在拉我的頭髮,試圖確定爲什麼。
在以下TSQL代碼中,它是插入Param表失敗。除了列名之外,Param表基本上與Method表相同。兩個插入都與Form表具有相似的外鍵關係,並且都將int值插入到ID列中。
當我運行SQL Server Profiler時,我被告知FormDB上有一個不允許插入的鎖。不過,我可以改變Param插入的select語句,它可以工作。我已經改變了在以下幾個方面,都在意義上的「工作」的,他們不引起堵塞的問題:
- 取代了帕拉姆選擇與方法選擇,同時保持所述插件參數(確切相同的列表示參數選擇)
- 將@ newKey替換爲現有表單的有效整數。
- 刪除了「從」帕拉姆的部分選擇和硬編碼的芳族聚酰胺單int值(即選擇@newKey,1,@modifyDate,@modifyUser)
我覺得我失去了我因爲我不明白爲什麼它不起作用。只有組合select語句中的三件事情時,insert纔會失敗 - @ newKey,ParamID和from語句。
我確保每個sproc都有SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,並且在必要時與nolock一起使用。
爲什麼我可以通過上述三種方案成功地插入Param表中,但是後面代碼中的參數插入失敗?爲什麼我不會在分析器中收到相同的鎖定消息?在此過程中還有大約5個其他插頁遵循相同的模式。他們都工作沒有問題。
任何想法?謝謝。
USE [PROD]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[HELPSPROC]
@oldKey int
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
declare @newKey int
, @spKey int
, @modifyDate datetime = getdate()
, @modifyUser varchar(30) = 'User'
/*
a bunch of stuff happens here, including setting the @spKey value.
this all happening correctly -- we have a valid integer value when we go into the next part
*/
---------------FORM---------------
INSERT INTO FormDB.dbo.Form
(formtype, formstatus, modifydate, modifyuser)
Select
'TestFormType', 'DRAFT', @modifyDate, @modifyUser
From FormDB2.dbo.Form f
Where f.Pkey = @oldKey
--grab the new int identifier -- works
set @newKey = (select scope_identity())
/*
stuff happens here. all is good in this part
*/
---------------Param---------------
INSERT INTO FormDB.dbo.Param
(FormKey, ParamID, ModifyDate, ModifyUser)
select @newKey, p.ParamID, @modifyDate, @modifyUser
from PROD.dbo.Table1 apd
inner join PROD.dbo.ParameterTable p
on apd.TableTwoKey = p.TableTwoKey
where apd.PKey = @spKey
---------------Method---------------
INSERT INTO FormDB.dbo.Method
(FormKey, MethodID, ModifyDate, ModifyUser)
select @newKey, r.MethodID, @modifyDate, @modifyUser
from PROD.dbo.Table1 apd
inner join PROD.dbo.MethodTable r
on apd.TableTwoKey = r.TableTwoKey
where apd.PKey = @spKey
/*
one more insert ...
*/
RETURN 1
END
GO
你是什麼意思「有一個鎖在FormDB上」? – Alex
Hi @Alex。從我使用SQL Profiler,活動監視器和[Microsoft](https://support.microsoft.com/en-us/help/271509/how-to-monitor-blocking-in- sql-server-2005-and-in-sql-server-2000),我可以看到一個SPID(狀態爲睡眠狀態並等待命令)阻止當前插入另一個SPID(掛起狀態)。 –