Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 X-блокировка при INSERT  [new]
JustCurious
Guest
Добрый день.

Не могу взять в толк, на какой ресурс при вставке записи может накладываться эксклюзивная блокировка, если по сути эта самая запись ещё не существует?
Есть, скажем, кластерный индекс, в середину его диапазона вставляется новая запись. Что при этом блокируется? Страница?
29 дек 11, 14:17    [11845777]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
А потрейсить профайлером?

Как минимум, будет заблокирована вставленная запись.
29 дек 11, 14:19    [11845792]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
JustCurious
Guest
Гавриленко Сергей Алексеевич
А потрейсить профайлером?

Как минимум, будет заблокирована вставленная запись.


Т.е. блокировка наложится после вставки, я правильно понял?
29 дек 11, 14:20    [11845804]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
JustCurious
Добрый день.

Не могу взять в толк, на какой ресурс при вставке записи может накладываться эксклюзивная блокировка, если по сути эта самая запись ещё не существует?
Есть, скажем, кластерный индекс, в середину его диапазона вставляется новая запись. Что при этом блокируется? Страница?
Называется Блокировка диапазона ключей
Там и пример есть на вставку
29 дек 11, 15:46    [11846547]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
JustCurious
Guest
Вроде разобрался )

CREATE TABLE dbo.t1 
	(
		 ID int IDENTITY(1,2) NOT NULL PRIMARY KEY
		,Name varchar(512) NULL DEFAULT ('1234567890012345678901234567891234567891234567891234567890'))
GO		

WHILE SCOPE_IDENTITY() < 2000
BEGIN
	INSERT INTO dbo.t1
	DEFAULT VALUES;
END

SET IDENTITY_INSERT dbo.t1 ON
GO

INSERT INTO dbo.t1 (id, Name)
VALUES (450, DEFAULT);

SET IDENTITY_INSERT dbo.t1 OFF
GO

В профайлере есть записи

Lock:Acquired	1:148	 	 8 - IX		6 - PAGE
Lock:Acquired	(61b5a2fe0b6d)	 15 - RangeI-N 	7 - KEY
Lock:Acquired	(98f9c969ee61)	 5 - X		7 - KEY
Lock:Released	(98f9c969ee61)	 5 - X		7 - KEY
Lock:Released	1:148		 8 - IX		6 - PAGE


Т.е. накладывается блокировка намерения на страницу, потом блокируется диапазон ключей (интересно узнать, он состоит из 2-х ключей 449 и 451?), потом запрашивается блокировка на (только что вставленный?) ключ.
А как по 61b5a2fe0b6d и 98f9c969ee61 определить ресурс?
29 дек 11, 16:03    [11846666]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
JustCurious
Guest
alexeyvg
JustCurious
Добрый день.

Не могу взять в толк, на какой ресурс при вставке записи может накладываться эксклюзивная блокировка, если по сути эта самая запись ещё не существует?
Есть, скажем, кластерный индекс, в середину его диапазона вставляется новая запись. Что при этом блокируется? Страница?
Называется Блокировка диапазона ключей
Там и пример есть на вставку

Спасибо, пару вопросов если можно...

Есть таблица со значениями (0,4,5,6,10)
Если я всё правильно понял, то при выборке
SELECT * FROM dbo.t WHERE ID BETWEEN 0 AND 10

заблокируется диапазон ключей от 1 до 10 (при соотв. уровне изоляции). Диапазон будет включать начальное и конечное значение
а при вставке
INSERT 
INTO dbo.t 
VALUES (1,3,8)

будет 2 диапазона? И они будут состоять только из значений 4 и 10 (а не так как в варианте с SELECT'ом - 0..10)? Т.е. блокируется диапазон со значением ключа "4" - т.е. другим транзакциям нельзя вставить ничего, что должно быть вставлено сразу слева от него (например, 1, 2 или 3), для "10" - нельзя будет вставить 7, 8 или 9.

В статье написано, что "Блокировка диапазона ключей в режиме RangeI-N необходима только для проверки диапазона, поэтому она не поддерживается в течение всего времени существования выполняющей вставку транзакции. Другие транзакции могут вставлять или удалять значения, находящиеся перед вставленным значением или после него. "

А как же тогда другие транзакции смогут узнать, что если им надо вставить 7, то блокировать диапазон надо не с ключа "10", а с ключа "8" в то время как на "8" наложена Х-блокировкадо конца транзакции, что не даёт возможность "обнаружить" это значение?

Объяснил как смог )
29 дек 11, 19:56    [11847733]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
JustCurious
А как же тогда другие транзакции смогут узнать, что если им надо вставить 7, то блокировать диапазон надо не с ключа "10", а с ключа "8" в то время как на "8" наложена Х-блокировкадо конца транзакции, что не даёт возможность "обнаружить" это значение?

Объяснил как смог )


Я не совсем поняла... но рискну предположить, что "другие транзакции" будут ждать, пока "возможность "обнаружить" это значение" не появится. В sp_lock это будет выглядеть как блокировка на "8" со статусом Wait.
30 дек 11, 06:10    [11848906]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
JustCurious
Member

Откуда: UA
Сообщений: 94
Кудряшка
JustCurious
А как же тогда другие транзакции смогут узнать, что если им надо вставить 7, то блокировать диапазон надо не с ключа "10", а с ключа "8" в то время как на "8" наложена Х-блокировкадо конца транзакции, что не даёт возможность "обнаружить" это значение?

Объяснил как смог )


Я не совсем поняла... но рискну предположить, что "другие транзакции" будут ждать, пока "возможность "обнаружить" это значение" не появится. В sp_lock это будет выглядеть как блокировка на "8" со статусом Wait.

Хм... Но ведь увидеться эта "8" может только при READ UNCOMMITTED, я правильно понимаю? А если уровень изоляции выше?
11 янв 12, 22:46    [11888974]     Ответить | Цитировать Сообщить модератору
 Re: X-блокировка при INSERT  [new]
ZOOKABAKODER
Member

Откуда:
Сообщений: 178
Ну если на вскидку...
Открой два запроса в студии с запросом такого типа
begin tran 

insert into smth (somfield) values (somefing);
-- досюдва
comit tran 

Сначала в первом окне выполни до камента "-- досюдва" а потом во втором всё попробуй. И посмотри в вьюхе транлоков что за блокировки. Поиграй с разными значениями для вставки.

А чтоб расшифровать "Lock:Acquired (61b5a2fe0b6d)", выполни запрос типа:
BEGIN TRAN 

SELECT * FROM smth WITH(XLOCK) WHERE smth.somekey = @somekey

посмотри в транлоках какой KEY словил Lock. Потом конечно не забудь "commit tran" сделать. Можно вообще в цикле повыполнять запросы и выборку из транлоков, и отчёт составить. Например так:
CREATE TABLE [dbo].Test(
	[My_id] [int] NOT NULL PRIMARY KEY
) 
GO

DECLARE @MyId INT;

SET @MyId = 0;

WHILE @MyId < 20
BEGIN
	INSERT INTO dbo.Test(My_id) VALUES(@MyId);
	SET @MyId = @MyId + 1;
END

DECLARE @MyId INT, @MyKey NVARCHAR(256);
DECLARE @rpt TABLE 
(	MyId INT NOT NULL
,	MyKey NVARCHAR(256) NOT NULL)
;
SET @MyId = 0;

WHILE 1 = 1
BEGIN
	BEGIN TRAN;

	SELECT	@MyId = My_id 
	FROM	[dbo].[Test] WITH(XLOCK)
	WHERE	My_id = @MyId;
	
	IF @@ROWCOUNT = 0
	BEGIN
		COMMIT TRAN;
		BREAK;
	END
	
	SELECT	@MyKey = dtl.resource_description
	FROM	sys.dm_tran_locks AS dtl
	WHERE	
		dtl.resource_type = 'KEY'
	AND	dtl.request_session_id = @@SPID;
		
	COMMIT TRAN;
	
	INSERT INTO @rpt(MyId, MyKey) VALUES(@MyId, @MyKey);

	SET @MyId = @MyId + 1;
END

SELECT	*
FROM	@rpt;


Для диапазонов аналогично...
11 янв 12, 23:37    [11889240]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить