Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / MSS и дедлок при запуске stored procedure... / 25 сообщений из 50, страница 1 из 2
16.03.2004, 13:04
    #32443389
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Привет всем!
Есть проблема.
Процедура на MSS работает в транзакции. Когда запускаю эту же самую процедуру из VC-6 стандартно через АDO в стресс режиме(одновременное обращение более чем одного клиента, то все работает. Если запускаю эту же процедуру из C# .NET в "многоюзерном режиме", то получаю регулярно
"Transaction (Process ID <номер>) was deadlocked on {lock} resources with another process and has been chosen as the deadlock victim. Rerun the transaction." .
В процедуре нет кода, который мог бы вызвать deadlock, кроме этого из сишного кода она работает!
Привожу кусок кода, вызывающего процедуру.
Может кто сталкивался с подобной проблемой?
Может какие-то ресурсы не освобождаю?
Заранее спасибо.
//////////////
IDbCommand command = null;
IDbConnection connection = null;

try
{
//здесь создается объекты в зависимост от базы(Oracle или MSS) имплементирующие один и тот же стандартный интерфейс
InitDBObjects(strProcName, new Hashtable(), ref connection, ref command);

command.CommandType = CommandType.StoredProcedure ;

IDbDataParameter dataParameter = null;

foreach(MyParam dbParam in Params)//from client
{
dataParameter = command.CreateParameter();
dataParameter.ParameterName = m_paramPrefixStoredProc dataParameter.Direction = dbParam.Direction;
object objValue = dbParam.Value;
dataParameter.Size = dbParam.Size;
dataParameter.Value = objValue;
command.Parameters.Add(dataParameter);
}

command.ExecuteNonQuery();

Results.Clear();

foreach(IDbDataParameter param in command.Parameters )
{
if(param.Direction == ParameterDirection.Output ||
param.Direction == ParameterDirection.InputOutput ||
param.Direction == ParameterDirection.ReturnValue)
Results.Add(param.ParameterName.Replace(m_paramPrefix, ""), param.Value);
}
}
catch(Exception e)
{
throw new MyException(e);
}
finally
{
//close connection
CleanupConnection(ref connection);
}
//////////////
...
Рейтинг: 0 / 0
16.03.2004, 19:04
    #32444370
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Дедлоки - это проблема хранимки и сервера а не клиента, приведи процедурку.
А лучше запусти трассу и посмотри кто кого лочит.

Magnus
...
Рейтинг: 0 / 0
16.03.2004, 19:13
    #32444381
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Кстати, один из вариантов - ловить номер ошибки(если не ошибаюсь 1251) и перезапускать транзакцию.

Magnus
...
Рейтинг: 0 / 0
16.03.2004, 19:37
    #32444410
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Для информации: триггеров нет на эту таблицу
после того, как добавил WITH (NOLOCK) - локинг ушел.
Где может быть дедлок? Все просто, по-моему....
Спасибо

CREATE PROCEDURE sp_formula
@formula_id varchar(30),
@calculationinterval int,
@lastvalue integer output,
@formulatext varchar(50) output

as
declare @period_type char (1)
declare @ap_last_value varchar(50)
declare @ap_last_date datetime
declare @ap_template varchar(50)
BEGIN TRANSACTION

select @period_type = period_type, @ap_last_date = ap_last_date, @formulatext = ap_template from ap_formula WITH (NOLOCK) where ap_formula_id = @formula_id


BEGIN

update ap_formula set ap_last_date = getdate(), ap_last_value =
(select convert(int,ISNULL(ap_last_value,0)) + @calculationinterval
from ap_formula where ap_formula_id = @formula_id) where ap_formula_id = @formula_id

select @lastvalue = convert(int,ap_last_value)
from ap_formula where ap_formula_id = @formula_id

END
COMMIT TRANSACTION
...
Рейтинг: 0 / 0
16.03.2004, 21:53
    #32444497
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
В трансакции не должно быть ничего лишнего, держи ее максимально короткой.
Итак:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE PROCEDURE sp_formula 
@formula_id varchar( 30 ), 
@calculationinterval int, 
@lastvalue integer output, 
@formulatext varchar( 50 ) output 

as 
declare @period_type char ( 1 ) 
declare @ap_last_value varchar( 50 ) 
declare @ap_last_date datetime 
declare @ap_template varchar( 50 ) 

BEGIN 
select @period_type = period_type, @ap_last_date = ap_last_date, @formulatext = ap_template from ap_formula where ap_formula_id = @formula_id 


BEGIN TRANSACTION 

update ap_formula set ap_last_date = getdate(), ap_last_value = 
(select convert(int,ISNULL(ap_last_value, 0 )) + @calculationinterval 
from ap_formula where ap_formula_id = @formula_id) where ap_formula_id = @formula_id 

COMMIT TRANSACTION

select @lastvalue = convert(int,ap_last_value) 
from ap_formula where ap_formula_id = @formula_id 

END 


Т.е. первым селектом ты ее и залочил.

Magnus
...
Рейтинг: 0 / 0
17.03.2004, 09:51
    #32444763
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
А где смысл транзакции тогда? В твоем варианте вообще не надо никакой транзакции!
В том коде, который ты прислал, при многопоточном обращении неизвестно, какой результат получит клиент! Если ты работал с этим, то сталкивался наверное!
...
Рейтинг: 0 / 0
17.03.2004, 10:31
    #32444863
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
EvgenyV

а в вашем случае транзакция и не нужна :)

PS> Поставьте лучше в начале SP
Код: plaintext
1.
2.
SET NOCOUNT ON
SET XACT_ABORT ON
...
Рейтинг: 0 / 0
17.03.2004, 10:59
    #32444960
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Есть одно маленькое "НО".
Когда пользуюсь вашими советами, получаю больше одного раза одно и тоже значение! А поскольку процедура обеспечивает возврат уникального номера/стринга, не могу ей пльзоваться!
Спасибо
...
Рейтинг: 0 / 0
17.03.2004, 11:16
    #32445004
Sa
Sa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
>Когда пользуюсь вашими советами, получаю больше одного раза одно и тоже значение! А поскольку процедура обеспечивает возврат уникального номера/стринга, не могу ей пльзоваться!

А поподробнее это почему же?
...
Рейтинг: 0 / 0
17.03.2004, 11:32
    #32445049
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Что делает процедура: берет последний номер прибавляет, допустим 1 и возвращает клиенту. Если два клиента получат один и тот же номер - очень плёхо :). Будет, например, два человека с одним и тем же номером паспорта... или банковского счета - выбирай, что лучше :)
...
Рейтинг: 0 / 0
17.03.2004, 15:01
    #32445556
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Да, стормозил я маленько. Явная транзакция тут вообще не нужна.
ap_formula_id уникальное значение?


Magnus
...
Рейтинг: 0 / 0
17.03.2004, 18:22
    #32446069
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Возможно вы привели не весь код - но для указанного фрагмента транзакция не нужна :)
...
Рейтинг: 0 / 0
17.03.2004, 22:20
    #32446263
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
В этом все дело, что уникальное. Самое прикольное, что если клиенты C++ COM, то все ок! А если .NET, но начинается эта фигня! Как я уже и писал WITH (NOLOCK) решает проблему и локировки нет и уникальность сохраняется. Все равно не могу понять, почему вообще локировался процесс...
Спасибо
...
Рейтинг: 0 / 0
17.03.2004, 22:25
    #32446265
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
funikovyuri - привел весь код! Почему же не нужна транзакзия ? Нужна. Тогда зачем вообще транзакция существует? Просто долго писать и объяснять почему :)
...
Рейтинг: 0 / 0
17.03.2004, 23:06
    #32446288
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Давайте разберемся, что есть ap_last_value?

При данныой конструкции и N клиентов если не блокировать таблицу, то всегда есть вероаятность что новый вызов успеет прочитать значение до апдейта.
Выходы:
1. Таки блокировать, ловить ошибку и перезапускать.
2. Использовать встроенные средства для разруливания ситуации, т.е. ap_last_value - identity. Выставляйте ему seed и возвращайте
Код: plaintext
 SCOPE_IDENTITY()


Вот это
Самое прикольное, что если клиенты C++ COM, то все ок! А если .NET, но начинается эта фигня
совсем не понятно. Проблема чисто серверная , отношения к клиенту не имеет. хм..
но если вы так говорите, давайте посмотрим.
Запустите трассу в обоих случаях и посмотрите что запускается на сервере.


Magnus
...
Рейтинг: 0 / 0
18.03.2004, 10:02
    #32446566
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Magnus, спасибо за советы. К сожалению, identity не могу использовать - поддержка предыдущих старых версий.
Единственная разница на трассировке
(с одинаковым по умолчанию фильтром сообщений. Может Вы знаете, какую полезную инфо можно добавить в трассировку?)
в том, что ADO client запускает каждый раз Audit Login, который включает в себя набор команд
-- network protocol: LPC
set quoted_identifier on
set implicit_transactions off
set cursor_close_on_commit off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set language us_english
set dateformat mdy
set datefirst 7

Я эти команды вставил в начало процедуры - никакого результата.
Спасибо
...
Рейтинг: 0 / 0
18.03.2004, 14:57
    #32447427
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Нравиться мне когда говорят о транзакции - а ставят nolock
...
Рейтинг: 0 / 0
18.03.2004, 15:43
    #32447553
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
да я понимаю...что ничего не понимаю...:)
на самом деле! без "no lock" в транзакции - blocking, без транзакции без "no lock" - некорректные данные. работает вариант с "no lock" в транзакции...почему? не знаю. пока работает - пусть работает :)
трогать не буду. как только упаду первый раз на "key violation" с полученным номером - буду думать :)
...
Рейтинг: 0 / 0
18.03.2004, 16:24
    #32447653
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Знач так,
set implicit_transactions off - это было в варинте без транзакции?

пробуем вот так:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

это должно быть установлено для каждого коннекта.
Вместе с транзакцией, как и было в начале.

Ждем результатов.


Magnus
...
Рейтинг: 0 / 0
18.03.2004, 16:37
    #32447694
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
EvgenyV

Я немного начинаю понимать :) В частности заметил output параметры...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE PROCEDURE sp_formula 
@formula_id varchar( 30 ), 
@calculationinterval int, 
@lastvalue integer output, 
@formulatext varchar( 50 ) output 
as 
SET NOCOUNT ON
SET XACTABORT ON

declare @period_type char ( 1 ) 
declare @ap_last_value varchar( 50 ) 
declare @ap_last_date datetime 
declare @ap_template varchar( 50 ) 
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION 

select @period_type = period_type, @ap_last_date = ap_last_date, @formulatext = ap_template from ap_formula where ap_formula_id = @formula_id 

update ap_formula set ap_last_date = getdate(), ap_last_value = 
(select convert(int,ISNULL(ap_last_value, 0 )) + @calculationinterval 
from ap_formula where ap_formula_id = @formula_id) where ap_formula_id = @formula_id 


select @lastvalue = convert(int,ap_last_value) 
from ap_formula where ap_formula_id = @formula_id 

END 
COMMIT TRANSACTION


Такое точно будет работать

А вот вариант получше - но это только мои догадки - так как я не понял зачем надо было last_value брать новое а ap_last_date - старое :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
CREATE PROCEDURE sp_formula 
@formula_id varchar( 30 ), 
@calculationinterval int, 
@lastvalue integer output, 
@formulatext varchar( 50 ) output 
as 
SET NOCOUNT ON
SET XACTABORT ON

declare @period_type char ( 1 ) 
declare @ap_last_value varchar( 50 ) 
declare @ap_last_date datetime 
declare @ap_template varchar( 50 ) 
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRANSACTION 

update ap_formula set ap_last_date = getdate(), ap_last_value = 
(select convert(int,ISNULL(ap_last_value, 0 )) + @calculationinterval 
from ap_formula where ap_formula_id = @formula_id) where ap_formula_id = @formula_id 

select @lastvalue = convert(int,ap_last_value),@period_type = period_type, @ap_last_date = ap_last_date, @formulatext = ap_template from ap_formula where ap_formula_id = @formula_id 

END 
COMMIT TRANSACTION
...
Рейтинг: 0 / 0
18.03.2004, 16:38
    #32447698
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
еще могу сказать почему у вас работает вариант с nolock :)
...
Рейтинг: 0 / 0
18.03.2004, 16:42
    #32447705
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
А вот READ UNCOMMITTED думаю тут лишнее. Здесь вариант довольно простой, вызов один и тот же, тот же порядок операторов, поэтому READ COMMITTED с транзакцией. Дедлоков быть не должно. By Design.



Magnus
...
Рейтинг: 0 / 0
18.03.2004, 16:58
    #32447752
funikovyuri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Ой... Там конечно же должен быть READ COMMITED ....
...
Рейтинг: 0 / 0
18.03.2004, 23:51
    #32448287
EvgenyV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
Во-первых, всем спасибо!!!!!
Зашел из дома посмотреть, не выдержал:)
По поводу ap_last_date - просто я выбросил лишний код, который использует в дальнейшем этот параметр. В данном случае он совсем не нужен. Работает только приведенный мной кусок кода.

funikovyuri - А что с out параметрами? Они каким-то образом влияют?

Народ, если мне не изменяет память, если мы пишем BEGIN TRANSACTION, то по умолчанию это - BEGIN TRANSACTION READ COMMITED.

Спасибо
Буду на работе проверю все варианты!
...
Рейтинг: 0 / 0
19.03.2004, 00:30
    #32448296
Magnus23
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MSS и дедлок при запуске stored procedure...
А вот здесь начинается самое интересное. При использовании COM для связи с сиквелом уровень насильно выставляется как Serializable.
Так что, попробуйте
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Magnus
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / MSS и дедлок при запуске stored procedure... / 25 сообщений из 50, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]