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

Откуда: Рязань
Сообщений: 141
Здравствуйте.

Из срр-кода вызывается хранимка, из которой вызывается sp_getapplock:

declare @spresult int
exec @spresult = sp_getapplock @Resource='MY_TABLE', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeOut=3000
return @spresult


Перед этим в срр-коде вызывается ADODB::Connection::BeginTrans(). На выходе получаем -999 - "Indicates a parameter validation or other call error."


Если эту же хранимку вызывать из Management Studio, залогинившись под тем же пользователем, что и срр-код (не sa), то на выходе ноль, т.е. блокировка получена. Вызывается вот так:

DECLARE @ret int
begin transaction
exec @ret = my_proc
select @ret
rollback transaction


Пробовал вызывать с @LockOwner='Session'. Из Management Studio - снова работает, из срр-кода - отказ по тайм-ауту, код -1.

В срр-коде попробовал создавать новый ADODB::Connection для этого вызова - не помогло.


Никто не подскажет:
1) есть ли разница между открытиями транзакций, и если да, то в чем она? (хотя это не так важно, ведь и при @LockOwner='Session' не работает)
2) как заставить sp_getapplock работать из ADO? какая может быть "other call error"?
3) есть ли другой способ получить блокировку таблицы, пригодный для вызова из ADO?
15 фев 12, 13:48    [12095436]     Ответить | Цитировать Сообщить модератору
 Re: не могу получить блокировку таблицы при вызове sp_getapplock из ADO  [new]
1
Guest
вставить еще один Begin tran в хранимую процедуру
затем declare @spresult int
exec @spresult = sp_getapplock @Resource='MY_TABLE', @LockMode='Exclusive', @LockOwner='Transaction', @LockTimeOut=3000
IF @@TRANCOUNT>0 commit tran
return @spresult
15 фев 12, 13:54    [12095504]     Ответить | Цитировать Сообщить модератору
 Re: не могу получить блокировку таблицы при вызове sp_getapplock из ADO  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
ADO не порождает явных транзакций, а работает в режиме implicit_transaction on. Соответственно, ваш вызов BeginTrans() транзакцию не стартует и sp_getapplock с @LockOwner = 'transaction' благополучно обламывается.

А в случае с @LockOwner = 'session' блокировка уже установлена другим сеансом, поэтому ваш отваливается по таймауту.
15 фев 12, 14:01    [12095580]     Ответить | Цитировать Сообщить модератору
 Re: не могу получить блокировку таблицы при вызове sp_getapplock из ADO  [new]
teo609
Member

Откуда: Рязань
Сообщений: 141
invm,

Вы меня натолкнули на идею. Из описания imlicit_transactions, насколько могу видеть, никак не следует, что ADO::BeginTrans не открывает транзакицю, но проверка @@tranCount, упомянутой 1, показала, что он равен нулю после ADO::BeginTrans. Перешел на выполнение запросов "set implicit_transactions off", затем "begin tran" из срр-кода. Теперь @@tranCount равен 1 в момент вызова sp_getapplock. Теперь она отваливается по тайм-ауту.

В поисках других подключений (возможно блокирующих) сделал select * from sys.sysprocesses в момент ожидания тайм-аута. (База тестовая, к ней кроме моего cpp-кода и Management Studio никто не подключается, поэтому большого числа соединений нет.) Лишь одно подключение имеет status=suspending, lastwaittype=LCK_M_X, waitresource=APP: 5:0:[MY_TABLE]: (0fd6367), open_tran=1. У остальных соответственно, sleeping, MISCELLANEOUS, , 0. Т.е. других подключений нет, насколько можно видеть. А блокировку все равно получить не удается. С чем это может быть связано?


1,
какой смысл в дополнительной транзакции для блокировки уровня Transaction, если при этом она сразу же коммитится? Надо не просто получить блокировку, а получить и удерживать ее на время изменений в таблице.
15 фев 12, 16:11    [12096876]     Ответить | Цитировать Сообщить модератору
 Re: не могу получить блокировку таблицы при вызове sp_getapplock из ADO  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Установленные пользовательские блокировки можно посмотреть так:
select
 *
from
 sys.dm_tran_locks
where
 resource_type = 'APPLICATION';
15 фев 12, 16:34    [12097098]     Ответить | Цитировать Сообщить модератору
 Re: не могу получить блокировку таблицы при вызове sp_getapplock из ADO  [new]
teo609
Member

Откуда: Рязань
Сообщений: 141
invm,

Спасибо. Это было оно. Висела одна блокировка. Видимо, в порядке разработки/экспериментирования создал.
Перезапустил Management Studio - все работает.

Глубокая благодарность.
15 фев 12, 16:52    [12097314]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить