![]() |
#14 |
Участник
|
SQL Server 2005 Enterprice Edition
База данных работает в версионном режиме. Имеется простенькая табличка: CREATE TABLE [dbo].[_Table1]( [id] [varchar](10) COLLATE Cyrillic_General_CI_AS NOT NULL, [name] [varchar](50) COLLATE Cyrillic_General_CI_AS NOT NULL, [flag] [int] NOT NULL, [dataareaid] [varchar](10) COLLATE Cyrillic_General_CI_AS NOT NULL Первичный ключ PK__Table1 в ней: по полям dataareaid и id , ключ является кластерным. Есть еще индекс IX__Table1 по полям dataareaid и flag. Использование поля dataareaid в качестве первого поля во всех индексах и ключах здесь принципиально: в Аксапте это поле является идентификатором компании, используется практически во всех таблицах, и включается во все ключи и индексы как первое поле. Мы хотим выполнить запрос на обновление записи (записей) в этой таблицы: SELECT * FROM _TABLE1 WITH( INDEX(PK__Table1), UPDLOCK) WHERE dataareaid='comp' and (ID='2') Причем выполнить в виде курсора используя хранимые процедуры sp_cursorprepexec, sp_cursorfetch и т.д. В результате список операций получается такой: SET TRANSACTION ISOLATION LEVEL READ COMMITTED begin transaction DECLARE @p1 int SET @p1=-1 DECLARE @p2 int SET @p2=0 DECLARE @p5 int SET @p5=2 DECLARE @p6 int SET @p6=2 DECLARE @p7 int SET @p7=-1 exec sp_cursorprepexec @p1 output,@p2 output, NULL, N'SELECT * FROM _TABLE1 WITH( INDEX(PK__Table1), UPDLOCK) WHERE dataareaid=''comp'' and (ID=''2'')', @p5 output,@p6 output,@p7 output select @p1, @p2, @p5, @p6, @p7 exec sp_cursorfetch 180150023,2,1,1 exec sp_cursor 180150023,40,1 exec sp_cursorclose 180150023 commit Рассмотрим по порядку то, что здесь выполняется. Оператор exec sp_cursorprepexec парсит и выполняет запрос, здесь важно обратить внимание на 2 параметра: p5 и p6, которые представляют из себя тип курсора (значение 2 соответствует динамическому типу) и тип конкурентности (2 – scroll locks) ,т.е. записи блокируются в тот момент, когда они выбираются командой fetch и разблокируются при переходе к следующей записи. Выполняю эти действия пошагово, и смотрю блокировки в базе данных После exec sp_cursorprepexec никаких блокировок нет. После sp_cursorfetch блокируется ключ индекса PK__Table1, что в общем то никаких вопросов не вызывает. А вот после выполнения exec sp_cursor возникает блокировка индекса IX__Table1 которая вызывает массу вопросов: я выбираю на изменение запись по значению первичного ключа, это значение первичного ключа должно заблокироваться, оно блокируется как и положено…но причем тут индекс по совершенно другому полю, почему он блокируется? Причем блокировка индекса PK__Table1 проходит безобидно: я могу из другой транзакции выбрать точно так же на обновление любую другую запись этой же таблицы. А вот блокировка IX__Table1 приводит к тому, что попытка из другой транзакции выбрать на обновление любую запись из этой же таблицы приведет к блокировке ожидания, и запрос не выполнится до тех пор, пока первая транзакция не разблокирует индекс. Такое поведение SQL Server, естественно безобидным назвать нельзя, поэтому хотелось бы разобраться из-за чего такое возникает |
|
Теги |
ax3.0, sql server |
|
![]() |
||||
Тема | Ответов | |||
Проблема с единицей измерения | 4 | |||
Проблема с созданием объекта | 33 | |||
Проблема с налогами | 3 | |||
Проблема: русские шрифты в отчетах, формируемых на сервере. | 3 | |||
Проблема с правами доступа | 1 |
|