Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Блокировка объекта базы данных / 4 сообщений из 4, страница 1 из 1
20.09.2020, 21:19
    #40000688
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка объекта базы данных
Решаю такую проблему: есть ASP.NET MVC приложение. В нем работает фоном поток - достает из MS SQL Server объекты и обрабатывает их, делая REST вызовы к стороннему сервису. Когда один экземпляр приложения, то всё нормально. А вот если несколько, то возможна ситуация когда в один момент времени два экземпляра приложения ASP.NET достанут из базы один и тот же объект и будут обрабатывать его - например сделают два одинаковых вызова по REST API. Поэтому я решил добавить к объекту поле lock, сингнализирующее, что объект обрабатывается экземпляром приложения и другим экземплярам недоступен. Т.е некий аналог мьютекса. Вопрос - правильно ли я реализовал свою задумку:

Код: 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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
CREATE PROCEDURE dbo.algo_GetLockStatus(@RealUID UNIQUEIDENTIFIER)
AS 

  BEGIN
     
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

    BEGIN TRANSACTION;

     BEGIN TRY -- --------------------------------------------------------------

      IF 0 = (SELECT lock FROM algo_RealProcesses WHERE @RealUID = uid_obj )
        BEGIN
              UPDATE algo_RealProcesses 
              SET lock = 1, locked_date = GETDATE()
              WHERE @RealUID = uid_obj

              IF @@TRANCOUNT > 0
                 COMMIT TRANSACTION;
              
              RETURN 1;
        END
      ELSE
        BEGIN
              IF @@TRANCOUNT > 0
                 COMMIT TRANSACTION;
              
              RETURN 2;
        END

     END TRY -- ------------------------------------------------------------------

     BEGIN CATCH

      IF @@TRANCOUNT > 0
         ROLLBACK TRANSACTION;

      RETURN 3;

     END CATCH;
	
    IF @@TRANCOUNT > 0
       COMMIT TRANSACTION;

    RETURN 0;

  END

GO



Только когда ХП возвращает 1, то вызывавший её инстанс ASP.NET может работать с объектом.
...
Рейтинг: 0 / 0
20.09.2020, 22:05
    #40000694
Критик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка объекта базы данных
gepard1980,

Очередной велосипед...

https://docs.microsoft.com/ru-ru/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver15 READPAST
Указывает, что компонент Компонент Database Engine не считывает строки и страницы, заблокированные другими транзакциями. Если указан аргумент READPAST, блокировки уровня строк будут пропускаться, а блокировки уровня страниц — не будут. Компонент Компонент Database Engine будет пропускать строки вместо блокировки текущей транзакции до тех пор, пока блокировки не будут сняты. Например, предположим, что в таблице T1 есть один целочисленный столбец со значениями 1, 2, 3, 4, 5. Если транзакция A изменит значение 3 на 8, но еще не будет зафиксирована, то инструкция SELECT * FROM T1 (READPAST) возвратит значения 1, 2, 4, 5. Параметр READPAST главным образом используется для устранения конфликта блокировок при реализации рабочей очереди, использующей таблицу SQL Server. Средство чтения очереди, использующее аргумент READPAST, пропускает прошлые записи очереди, заблокированные другими транзакциями, до следующей доступной записи очереди, не дожидаясь, пока другие транзакции снимут свои блокировки.
...
Рейтинг: 0 / 0
20.09.2020, 22:32
    #40000697
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка объекта базы данных
gepard1980
Вопрос - правильно ли я реализовал свою задумку:
Почти.
Должно быть как-то так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
...
              UPDATE algo_RealProcesses with (readpast)
              SET lock = 1, locked_date = GETDATE()
              WHERE @RealUID = uid_obj and lock = 0;

              if @@rowcount = 0
               raiserror('Object not found or locked by another process', 16, 1);
...
...
Рейтинг: 0 / 0
20.09.2020, 22:50
    #40000700
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка объекта базы данных
Благодарю за подсказку!
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Блокировка объекта базы данных / 4 сообщений из 4, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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