Блокировки при вставке

Timid
Дата: 15.02.2010 14:53:50
Добрый день.

Есть некая хранимая процедура, вставляющая записи в таблицу. Вызывается она довольно часто. По ключевому полю создан кластерный индекс. Продедуру одновременно могут вызывать тысячи клиентов. Выполняет она приблизительно следующее:

INSERT INTO TxDeposit 
    (
	  AccountID
	, RequestAmount
	, PromoCode
	, Status
    )

VALUES (@AccountID, @Amount, @PromoCode, @Status)

Насколько я понял (с блокировками только начинаю ознакамливаться), т.к. первичный ключ является автоинкрементным, то создаётся горячая точка в "конце" таблицы, которая и является причиной блокировки при попытке вставить новую запись процедурой, вызванной разными клиентами. Пытаюсь воспроизвести ситуацию следующим образом:
сессия 69:
SET ROWCOUNT 4000
GO

DECLARE	@AID TABLE  
(
     ID	int IDENTITY(1,1)
    ,AccID	int

)
;

INSERT INTO @AID (AccID)
SELECT	a.ID
FROM	    Account a(NOLOCK)
CROSS JOIN  Account b(NOLOCK)
;

DECLARE	@AccountID  int
      , @Amount	    money
      , @PromoCode  nvarchar(20)
      , @Status	    tinyint
      , @cnt	    int	
;


SELECT	 @Amount    = 30
	,@PromoCode = ''
	,@Status    = 90
	,@cnt	    = MAX(ID)
FROM	@AID
;


BEGIN TRANSACTION

WHILE	@cnt <> 0
    BEGIN

	SELECT @AccountID = AccID
	FROM   @AID
	WHERE  [ID] = @cnt
	
	INSERT INTO TxDeposit 
	    (
		  AccountID
		, RequestAmount
		, PromoCode
		, Status
	    )

	VALUES (@AccountID, @Amount, @PromoCode, @Status)

       SET @cnt = @cnt - 1

    END	

ROLLBACK
;

Во время выполнения всавки выполняю в сессии 57 это:
BEGIN TRANSACTION

DECLARE	@AccountID  int
      , @Amount	    money
      , @PromoCode  nvarchar(20)
      , @Status	    tinyint
;


SELECT	 @AccountID = 598623
	,@Amount    = 30
	,@PromoCode = ''
	,@Status    = 90
;

INSERT INTO TxDeposit 
    (
	  AccountID
	, RequestAmount
	, PromoCode
	, Status
    )

VALUES (@AccountID, @Amount, @PromoCode, @Status)
;

 
DECLARE @locks	TABLE
    (
	 spid	int
	,dbid	int
	,ObjId	int
	,IndId	int    
	,[Type]	varchar(20)
	,Resource	varchar(20)
	,Mode	varchar(20)
	,Status	varchar(20)
    )
;

INSERT	INTO @locks
EXEC	sp_lock @@SPID

;

SELECT	*
FROM	@locks
WHERE	dbid  = DB_ID('Cash')
AND	objId = OBJECT_ID('TxDeposit')
;
 


COMMIT

Получаю в результате (сессия 69)

spid	dbid	ObjId	IndId	Type	Resource	Mode	Status
69	7	882818207	3	KEY	(1c01608343f4)      	X	GRANT
69	7	882818207	2	PAG	1:18181             	IX	GRANT
69	7	882818207	1	PAG	1:18273             	IX	GRANT
69	7	882818207	3	PAG	1:18624             	IX	GRANT
69	7	882818207	1	KEY	(9b00db1b72cd)      	X	GRANT
69	7	882818207	2	KEY	(fa00b9833f7a)      	X	GRANT
69	7	882818207	0	TAB	                    	IX	GRANT

А по сессии 57 (результаты сокращены):

spid	dbid	ObjId	IndId	Type	Resource	Mode	Status
57	7	0	0	DB	                                	S	GRANT
57	7	882818207	1	KEY	(a6000410f83a)                  	X	GRANT
57	7	882818207	2	KEY	(740014856d64)                  	X	GRANT
57	7	882818207	3	KEY	(220188f5e92c)                  	X	GRANT
57	7	882818207	3	KEY	(180208461cd1)                  	X	GRANT
57	7	882818207	1	KEY	(bd00adaa22bc)                  	X	GRANT
57	7	882818207	3	KEY	(b1011d45b512)                  	X	GRANT
57	7	882818207	3	KEY	(1a0149083263)                  	X	GRANT
57	7	882818207	2	KEY	(ce00279f98d8)                  	X	GRANT
57	7	882818207	2	KEY	(e60057e0354d)                  	X	GRANT
57	7	882818207	1	KEY	(be00746f55af)                  	X	GRANT


Вопрос заключается в следующем: почему не видно, что процесс 69 ожидает разблокировки ресурсов, заблокированных процессом 57?
Glory
Дата: 15.02.2010 14:56:48
Timid


Вопрос заключается в следующем: почему не видно, что процесс 69 ожидает разблокировки ресурсов, заблокированных процессом 57?

А где вы пытаетесь это увидеть ?
Timid
Дата: 15.02.2010 14:59:46
Glory
Timid


Вопрос заключается в следующем: почему не видно, что процесс 69 ожидает разблокировки ресурсов, заблокированных процессом 57?

А где вы пытаетесь это увидеть ?

Пытаюсь увидеть Wait в поле Status для сессии 69.
И запись в 69-й сессии вставляется успешно, до завершения транзакции в сесии 57...
Timid
Дата: 15.02.2010 15:06:51
ОЙ! Перепутал в посте айди сессий! :)
Там 69=57, а 57=69
Glory
Дата: 15.02.2010 15:08:07
Timid
Glory
Timid


Вопрос заключается в следующем: почему не видно, что процесс 69 ожидает разблокировки ресурсов, заблокированных процессом 57?

А где вы пытаетесь это увидеть ?

Пытаюсь увидеть Wait в поле Status для сессии 69.
И запись в 69-й сессии вставляется успешно, до завершения транзакции в сесии 57...

А почему блокировка нескольких индексных ключей сессии 57 должна мешать сесии 69 ?
Timid
Дата: 15.02.2010 15:10:37
Glory
Timid
Glory
Timid


Вопрос заключается в следующем: почему не видно, что процесс 69 ожидает разблокировки ресурсов, заблокированных процессом 57?

А где вы пытаетесь это увидеть ?

Пытаюсь увидеть Wait в поле Status для сессии 69.
И запись в 69-й сессии вставляется успешно, до завершения транзакции в сесии 57...

А почему блокировка нескольких индексных ключей сессии 57 должна мешать сесии 69 ?


Тогда поставлю вопрос по-другому: в каком случае произойдёт deadlock при выполнении инструкции

INSERT INTO TxDeposit 
	    (
		  AccountID
		, RequestAmount
		, PromoCode
		, Status
	    )

	VALUES (@AccountID, @Amount, @PromoCode, @Status)
Timid
Дата: 15.02.2010 15:11:51
Уточню - при многократном выполнении
Glory
Дата: 15.02.2010 15:12:05
Timid

Тогда поставлю вопрос по-другому: в каком случае произойдёт deadlock при выполнении инструкции

Когда произойдет deadlock, вы возьмете его граф и все узнаете
Timid
Дата: 15.02.2010 15:14:16
Glory
Timid

Тогда поставлю вопрос по-другому: в каком случае произойдёт deadlock при выполнении инструкции

Когда произойдет deadlock, вы возьмете его граф и все узнаете

К сожалению, я не имею доступ к продакшн-серверу, нам только спускаются отчёты о том, что такая-то процедура вызвала мёртвую блокировку
Glory
Дата: 15.02.2010 15:15:57
Timid
Glory
Timid

Тогда поставлю вопрос по-другому: в каком случае произойдёт deadlock при выполнении инструкции

Когда произойдет deadlock, вы возьмете его граф и все узнаете

К сожалению, я не имею доступ к продакшн-серверу, нам только спускаются отчёты о том, что такая-то процедура вызвала мёртвую блокировку

Ну так пускай они спустят граф мертвой блокировки