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

Откуда:
Сообщений: 19
Добрый день!
Есть некоторое приложение разбитое по потокам (не Service Broker) которое раз в секунду вызывает процедуры - каждый поток собственную процедуру
В одной из процедур используется IDENT_CURRENT для нахождения значения IDENTITY поля после вставки (код не мой, я обычно OUTPUT для таких вещей - не суть) Делаю высокую активность чтобы все это работало при высокой нагрузке Вижу проблемы с процедурой в которой юзается IDENT_CURRENT И подозреваю что IDENT_CURRENT возвращает какое то неверное значение (не соответствующее реалиям)
Вот псевдокод
insert into MyTable <список полей>
select <список>
select  @id = IDENT_CURRENT('MyTable')

<skipped>
<skipped>
<skipped>

update MyTable set поле1 = значение1,
                             поле2=значеие2
where ID = @id 

if @@rowcount<>1 
ОШИБКА 

И вот бывают случаи что логика вываливается на ошибку (@@rowcount<>1) А так как это в транзакции, процедура выполняется параллельно - апдейт начинает сканировать "не верные" диапазоны ключей и возникают всякие неприятные коллизии в т ч deadlock Но вот как раз первопричина этого неправильное значение выдаваемое IDENT_CURRENT - может быть такое? И поможет ли при этом замена на OUTPUT clause? Спрашиваю т к повторить эксперимент не могу так как стенд с приложением пока не работает, просто думаю над сложившейся ситуацией
Спасибо!
18 сен 19, 13:02    [21973189]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
invm
Member

Откуда: Москва
Сообщений: 8881
Как обычно, документацию никто не читает
https://docs.microsoft.com/ru-ru/sql/t-sql/functions/ident-current-transact-sql?view=sql-server-2017
Возврат последнего значения идентификатора, созданного для указанной таблицы или представления. Последнее созданное значение идентификатора может относиться к любому сеансу и любой области.

BredSpit
может быть такое?
Да.
Лечится заменой на SCOPE_IDENTITY
18 сен 19, 13:13    [21973196]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
BredSpit
Member

Откуда:
Сообщений: 19
invm Грешен - не читал ... Спасибо Не использую в коде IDENT_CURRENT
18 сен 19, 13:15    [21973198]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
msLex
Member

Откуда:
Сообщений: 7113
BredSpit
invm Грешен - не читал ... Спасибо Не использую в коде IDENT_CURRENT


SCOPE_IDENTITY тоже не панацея.

Используйте output

create table #t(id int not null identity, f int not null)

declare @id int
declare @t table(id int not null)



insert #t(f)
output inserted.id 
into @t(id)
select 1

select @id = id
from @t


select @id 

drop table #t 
18 сен 19, 13:37    [21973212]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
BredSpit
Member

Откуда:
Сообщений: 19
msLex Спасибо Тоже склоняюсь в сторону OUTPUT Читал(правда не для моего случая - а при параллелизме на серваке) что SCOPE_IDENTITY() может работать не корректно
18 сен 19, 13:43    [21973220]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29859
BredSpit
Читал(правда не для моего случая - а при параллелизме на серваке) что SCOPE_IDENTITY() может работать не корректно
При параллелизме она работает корректно.
Проблемы будут в инстед-триггерах.
18 сен 19, 13:49    [21973233]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
iap
Member

Откуда: Москва
Сообщений: 46909
msLex
BredSpit
invm Грешен - не читал ... Спасибо Не использую в коде IDENT_CURRENT


SCOPE_IDENTITY тоже не панацея.

Используйте output

create table #t(id int not null identity, f int not null)

declare @id int
declare @t table(id int not null)



insert #t(f)
output inserted.id 
into @t(id)
select 1

select @id = id
from @t


select @id 

drop table #t 
SCOPE_IDENTITY() и OUTPUT работают совершенно одинаково.
Если не считать, что OUTPUT может вернуть много вставленных строк, а не одну.
В том числе ни одно, ни другое не дадут вставленное IDENTITY, если есть триггер INSTEAD OF INSERT
18 сен 19, 14:40    [21973272]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
msLex
Member

Откуда:
Сообщений: 7113
iap
SCOPE_IDENTITY() и OUTPUT работают совершенно одинаково.




src
create table t (id int identity, f int )

declare @t table (id int identity(2,2), inserted_id int )

insert t
output inserted.id
into @t(inserted_id)
select 1

select [SCOPE_IDENTITY] = SCOPE_IDENTITY()
select * from @t


drop table t

18 сен 19, 14:57    [21973294]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
msLex
Member

Откуда:
Сообщений: 7113
iap
SCOPE_IDENTITY() и OUTPUT работают совершенно одинаково.




create table t (id int identity, f int ) 

declare @t table (id int identity(2,2), inserted_id int )

insert t 
output inserted.id
into @t(inserted_id)
select 1 

select [SCOPE_IDENTITY] = SCOPE_IDENTITY()
select * from @t


drop table t 
18 сен 19, 14:57    [21973295]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
iap
Member

Откуда: Москва
Сообщений: 46909
Вот, когда-то была тема (таких тем тут было видимо-невидимо!)
Ситуация с @@IDENTITY, помогите отловить
18 сен 19, 14:59    [21973298]     Ответить | Цитировать Сообщить модератору
 Re: IDENT_CURRENT параллельный вызов процедур и некоторые траблы  [new]
BredSpit
Member

Откуда:
Сообщений: 19
Спасибо всем откликнувшимся
18 сен 19, 16:00    [21973368]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить