powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Блокировка выполнения хранимой процедуры
6 сообщений из 6, страница 1 из 1
Блокировка выполнения хранимой процедуры
    #39808217
Игорь_UUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день

Предположим 5 сеансов работают с одной базы. Первый сеанс начал выполнение хранимой процедуры в которой был вызван BEGIN TRANSACTION, вопрос: как запретить выполнение хранимой процедуры всем остальным сеансам.. я бы сказал запретить параллельное выполнение, т.е. останавливаем выполнение до тех пор, пока идёт выполнение другим сеансом?


Суть такая, идёт приём телефонных звонков на 5-ти рабочих местах, АТС направляет телефонный вызов параллельно на все рабочие места, тот кто первый ответит, тот и начинает общение, у остальных происходит сброс. Сделано так, что при получении вызова, "db-клиент" сохраняет телефонный звонок вызывая хранимую процедуру. В самой хранимке имеется проверка, существует ли запись с таким номером телефоном в данный момент времени, если уже существует, то хранимка прекращает выполнение. Сейчас баг в том, что "раз через раз" при получении телефонного вызова происходит вставка 5-ти строк в БД, хотя должна быть одна.

Нашёл возможное место ошибки:

Код: sql
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.
29.
30.
SET NOCOUNT ON;

SET @Result = 0

BEGIN TRANSACTION

DECLARE @Ret INT
DECLARE @Direction INT = [dbo].[SIP_DirectionIn]()
DECLARE @CallKey INT
-- Исключение создание повторного вызова при параллельном вызове.
SET @CallKey = (
  SELECT
    [Key]
  FROM
    [SIP_Calls]
  WHERE
    [Phone] = @Phone AND [Direction] = @Direction AND [CreatedBySipPhone] = 1 AND 
    [StartedConversation] IS NULL AND DATEDIFF(SECOND, [CallDate], [dbo].[CORE_ServerDateToBranchDate]()) < 300
)

IF NOT @CallKey IS NULL
BEGIN
  COMMIT TRANSACTION
  SET @Result = @CallKey
  RETURN 0
END

...
... Далее если телефонного вызова с таким номером нет, то идёт создание записи
...



"Клиент" - закрытое скомпелированное ПО, но могу отредактировать бизнес логику... подскажите что тут лучше сделать?
...
Рейтинг: 0 / 0
Блокировка выполнения хранимой процедуры
    #39808219
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь_UUSвопрос: как запретить выполнение хранимой процедуры всем остальным сеансам.. я бы сказал запретить параллельное выполнение, т.е. останавливаем выполнение до тех пор, пока идёт выполнение другим сеансом?Использовать спкециально предназначенные для этого процедуры sp_getapplock / sp_releaseapplock
...
Рейтинг: 0 / 0
Блокировка выполнения хранимой процедуры
    #39808234
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь_UUS
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
-- Исключение создание повторного вызова при параллельном вызове.
SET @CallKey = (
  SELECT
    [Key]
  FROM
    [SIP_Calls]
  WHERE
    [Phone] = @Phone AND [Direction] = @Direction AND [CreatedBySipPhone] = 1 AND 
    [StartedConversation] IS NULL AND DATEDIFF(SECOND, [CallDate], [dbo].[CORE_ServerDateToBranchDate]()) < 300
)

IF NOT @CallKey IS NULL
BEGIN
  COMMIT TRANSACTION
  SET @Result = @CallKey
  RETURN 0
END

Ничего это "исключение" не исключает.
Такие вещи делаются через merge и без всяких предварительных селектов
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
merge into [SIP_Calls] t with (serializable)
using
 (values (@Phone, @Direction)) s(Phone, Direction) on t.Phone = s.Phone AND t.Direction = s.Direction AND t.CreatedBySipPhone = 1 AND 
    t.StartedConversation IS NULL AND DATEDIFF(SECOND, t.CallDate, dbo.CORE_ServerDateToBranchDate()) < 300
when not matched then
 insert ...
when matched then
 update
  set @CallKey = t.Key;

IF @CallKey IS not NULL
BEGIN
  COMMIT TRANSACTION
  SET @Result = @CallKey
  RETURN 0
END


И не придется сериализовать вызов процедуры.
...
Рейтинг: 0 / 0
Блокировка выполнения хранимой процедуры
    #39808325
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь_UUS,

используйте грязные чтения. Есть риск, но небольшой. Зато самая простая реализация.
...
Рейтинг: 0 / 0
Блокировка выполнения хранимой процедуры
    #39808347
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Игорь_UUSДобрый день

Предположим 5 сеансов работают с одной базы. Первый сеанс начал выполнение хранимой процедуры в которой был вызван BEGIN TRANSACTION, вопрос: как запретить выполнение хранимой процедуры всем остальным сеансам.. я бы сказал запретить параллельное выполнение, т.е. останавливаем выполнение до тех пор, пока идёт выполнение другим сеансом?

Создайте отдельную таблицу.
Далее, внутри транзакции произведите апдейт какой-либо записи этой таблицы, With (TABLOCKX, UPDLOCK), первой операцией.
Далее, внутри транзакции, расположите свои апдейты и т.д.
Собственно всё.
...
Рейтинг: 0 / 0
Блокировка выполнения хранимой процедуры
    #39808513
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterСоздайте отдельную таблицу.
Далее, внутри транзакции произведите апдейт какой-либо записи этой таблицы, With (TABLOCKX, UPDLOCK), первой операцией.
Далее, внутри транзакции, расположите свои апдейты и т.д.
Собственно всё.
Стисняюсь спросить...
А чем этот геморрой лучше sp_getapplock / sp_releaseapplock?
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Блокировка выполнения хранимой процедуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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