Try ...SET LOCK_TIMEOUT 0..catch

--__Александр__--
Дата: 24.01.2009 14:37:28
Пожалуйста объясните, почему так:
CREATE TABLE test.Trn (id int) 
insert test.Trn  VALUES(1)

Connection 1 Connection 2

  BEGIN TRAN    
          insert test.Trn  VALUES(2)
-------------------------------------------------------------------------------------------------
 
                                                                       BEGIN TRY
                                                                            SET LOCK_TIMEOUT 0
                                                                            SELECT * FROM test.Trn  
                                                                       END TRY
                                                                       begin catch end catch 
                                                                      --Return Only 1
                                                                      --Вот это не понятно почему так


  SELECT * FROM test.Trn  

Lock request time out period exceeded.
Это понятно почему так.
-------------------------------------------------------------------------------------------------
COMMIT TRAN

Соответсвенно вопрос: Почему, если селект обернуть в TRY ... CATCH, то он вернет 1, а не свалится с ошибкой?
Glory
Дата: 24.01.2009 15:24:35
А что должно вызвать ошибку SELECT ? какие блокировки SELECT не сможет наложить ?
--__Александр__--
Дата: 24.01.2009 15:50:41
Glory,
Ну у нас Connection 1 наложил монопольную блокировку на test.Trn. и мой селект не сможет наложить совмещаемую блокировку.
И именно поэтому этот блок Try ....catch вообще ничего не должен вернуть. А он почему то возвращает 1.
А вот если просто это селект запустить(не обарачивать его в Try ....catch), то как раз и будет та ошибка, которую я жду( Lock request time out period exceeded.)
Glory
Дата: 24.01.2009 15:52:57
--__Александр__--
Glory,
Ну у нас Connection 1 наложил монопольную блокировку на test.Trn. и мой селект не сможет наложить совмещаемую блокировку.

Вы эту блокировку где-то увидели ? Или просто думаете, что она существует ?
--__Александр__--
Дата: 24.01.2009 15:56:14
В книжке к этому примеру пишут:
The folllowing code sample uses the SET LOCK_TIMEOUT setting with a try/catch block to return only the rows found before the first dirty row is encountered by the SELECT statement.
Вот я в упор не понимаю, почему комба SET LOCK_TIMEOUT + try/catch возврашает
"only the rows found before the first dirty row".
--__Александр__--
Дата: 24.01.2009 16:20:09
Ну sys.dm_tran_locks показал вот что

OBJECT - IX(Блокировка с намерением монопольного доступа)
PAGE - IX(Блокировка с намерением монопольного доступа)
RID -X (Монопольная блокировка)
Glory
Дата: 24.01.2009 16:40:43
--__Александр__--
Ну sys.dm_tran_locks показал вот что

OBJECT - IX(Блокировка с намерением монопольного доступа)
PAGE - IX(Блокировка с намерением монопольного доступа)
RID -X (Монопольная блокировка)

Еще раз
Какие блокировки имеются непосредственно перед выполнением SELECT * FROM test.Trn ?
Ни до, ни после, а именно перед
--__Александр__--
Дата: 24.01.2009 18:14:50
Вот, перед выполнением:
OBJECT IX 53
PAGE IX 53
RID X 53


Это когда стоит LOCK_TIMEOUT 0
Во время выполнения:( SELECT * FROM test.Trn CROSS JOIN sys.dm_tran_locks )
OBJECT IS 59
OBJECT IX 53
PAGE IS 59
PAGE IX 53
RID X 53
Соответсвенно, 53 сессия - это где транзакция открыта,59 - текущая, откуда селект делаем.


Теперь, LOCK_TIMEOUT -1
RID X 53 GRANT
RID S 59 WAIT

Коллективная блокировка и монополная блокировка - не совместимы.
Поэтому 59 сессия ждет, пока 53 снимет монопольную блокировку.



Все равно не понятно, почему в блоке try ... catch select возвращает 1, а если не в блоке
try ... catch делать - то ошибка.
Glory
Дата: 25.01.2009 11:33:07
LOCK_TIMEOUT одного коннекта никак не может влиять на блокировки другого коннекта
Если коннект 53 установил
OBJECT IX 53
PAGE IX 53
RID X 53
то эти блокировки должны быть всегда одинаковы для коннекта 59
--__Александр__--
Дата: 25.01.2009 14:07:04
Так и есть.
Я просто для Теперь, LOCK_TIMEOUT -1 не все блокировки написал.Они такие же, как и для
LOCK_TIMEOUT 0, только добавляется RID S 59 WAIT.