:: Visual Foxpro, Foxpro for DOS
Запрет одновременного редактирования файла
lili
Автор

Сообщений: 472
Откуда: Сыктывкар
Дата регистрации: 07.11.2005
Приветствую всех!
На СКЛ-сервере в БД есть таблица tblFiles для хранения файлов.
Содержимое файлов хранится в поле content(varbinarymax).
Для редактирования файла делаю так:
Заполняю кусрос-адаптер для данной таблицы.
lcFile=c:\tmp\<тут имя файла>, то есть размещаю локально.
COPY MEMO tblFiles.content TO (lcFile)
Открываю файл в нужном приложении (прописаном в ОС для данного вида файлов),
редактирую, сохраняю файл в поле content через tableupdate().
Программа многопользовательская и логично возникла задача запретить одновременное редактирование файла
несколькими пользователями.
Какие тут могут быть решения?
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
PaulWist

Сообщений: 14761
Дата регистрации: 01.04.2004
Способ первый (неправильный), наложить монопольную блокировку на строку хинтом xlock

При "начале редактирования"

begin tran
select * from tblFiles with (xlock) where id = ...
-- тут на клиенте ходим пить чай, редактируем файл
-- потом нажимаем кнопку "Сохранить" с командой
commit

Разбор

Способ второй, идеологически правильный при условии, что к табличке будут обращаться исключительно через API программы - это Блокировка приложения


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 3 раз(а). Последнее : PaulWist, 10.04.24 15:04
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
lili
Автор

Сообщений: 472
Откуда: Сыктывкар
Дата регистрации: 07.11.2005
Как-то все это "не очень" удобно для юзеров.
По-хорошему, юзеру должно быть видно, кто и во сколько занял файл на редактирование.
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
PaulWist

Сообщений: 14761
Дата регистрации: 01.04.2004
Ну, ни кто не мешает в имя ресурса запихать "что-то полезное", например ID таблички и время начала блокировки Прилржения.

DECLARE
@result int,
@Resource nvarchar(255) = 'Редактируется файл ' + convert(varchar(20), getdate(), 104);
EXEC @result = sp_getapplock @Resource ,
@LockOwner= 'Session',
@LockMode = 'Exclusive';
select * from sys.dm_tran_locks where resource_type = N'APPLICATION' and resource_description like '%Редактируется файл%'


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
of63

Сообщений: 26041
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
() Вот-вот, тоже также изначально сделал "блокировку" в проге - создаю флаг, что де "открыл для записи такой-то ID". Фмзически ничего не блокируется, то программа создания флага читает наличие уже созданного флага "заблокирован ID". Т.е. БД никогда не заблокирована "ковырятелями в носу", а только на момент физической записи в БД (короткий момент)
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
Владимир Максимов

Сообщений: 14154
Откуда: Москва
Дата регистрации: 02.09.2000
Зависит от того, что именно вкладывается в понятие "одновременное". И вообще, сколько времени может продолжаться сам процесс "редактирования"?


    1. Добавить служебные поля с информацией о "блокировке"
    2. Блокировка средствами SQL
    3. Оптимистическая стратегия обновления


Что есть "достоинства", а что "недостатки" для каждого варианта - зависит от решаемой задачи. Т.е. от самого понятия "одновременно" применительно к процессу редактирования

1. Добавить служебные поля с информацией о "блокировке"

Собственно, это "закат солнца вручную" В таблицу tblFiles (или для этих целей создать новую таблицу) добавляются поля

- Кто заблокировал (код пользователя)
- Когда заблокировал (дата/время)
- Поля с дополнительной информацией, если необходимо. Например, из какой функции была выполнена блокировка

Т.е. логика такая

1. Если все служебные поля - пустые, то запись не блокирована можно установить блокировку
2. Под "блокировкой" понимается факт заполнения служебных полей
3. Соответственно, "снятие блокировки" - это очистка служебных полей

Достоинства/Недостатки

- Наглядность и понятность для пользователя. Поля с информацией о блокировке можно отобразить на форме
- Время блокировки - не ограничено. Дни/недели/месяцы
- Для снятия блокировки надо дать специальную команду (очистить поля). Если по каким-то причинам команды не было, то блокировка будет висеть "вечно", даже если уже никто ничего не редактирует. Обычно эта проблема решается служебной утилитой по очистке полей

2. Блокировка средствами SQL

это то, что Паша описал

Достоинства/Недостатки

- Простота реализации
- В случае разрыва соединения блокировка снимается автоматически
- Неочевидность и не наглядность для пользователя. Требует специальных усилий по "расшифровке" того, кто и когда заблокировал


3. Оптимистическая стратегия обновления

Собственно, это вопрос из цикла: а оно действительно надо?

Клиент-серверные приложения "по определению" работают в режиме оптимистической буферизации. Т.е. никто ничего не блокирует, но при записи делается проверка того факта, что за время внесения изменения пользователем кто-то другой уже успел внести изменения. И если это действительно так, то либо запрет сохранения с сообщением пользователю, либо запись поверх изменений другого пользователя

Разумеется, поля varbinary(max) сравнить проблематично и обычно для подобных "сверок" используют поля типа TimeStamp. В MS SQL для этого есть специальный тип данных, но, в общем случае, это может быть и обычный счетчик. Каждый Update увеличивает значение счетчика на единицу. Если при попытке записать текущее значение TimeStamp отлично от значения, которое было при чтении, то запись была изменена другим пользователем

Если требуется знать кто/когда внес последние изменения, то создают еще соответствующие поля с названиями вроде ModifedBy, ModifiedDateTime в которые записывают соответствующие значения при любой модификации. Наряду с обновлением поля TimeStamp

Достоинства/Недостатки

- Стандартный режим работы клиент-серверного приложения
- Нельзя запретить вносить изменения разным пользователям "одновременно"
- Кроме решения основной задачи имеем некий "лог" изменения. Видно кто и когда последний изменял запись. Правда, не ясно, что именно в записи было изменено, но это уже другой вопрос


------------------------

PS: Есть еще вариант "скрестить ежа с ужом"

Т.е. блокировка средствами SQL через sp_getapplock, но дополнительно, в отдельной служебной таблице записывать все необходимую сопутствующую информацию кто/когда/зачем установил блокировку по этому ресурсу. Идентификатор записи в этой служебной таблице - имя ресурса

Таблицу можно даже не очищать при снятии блокировки. Своеобразный "лог" того, кто и когда блокировал ресурс



Исправлено 2 раз(а). Последнее : Владимир Максимов, 14.04.24 20:44
Ratings: 1 negative/2 positive
Re: Запрет одновременного редактирования файла
shumik73

Сообщений: 554
Откуда: Алматы
Дата регистрации: 10.05.2006
Запрет на редактирование файла - раскрыл 2 темы:
1) Это хранение, выгрузку и загрузку файла
2) Блокировка при совместной работе пользователей
При чем вторая тема главная

С подобной проблемой сталкиваюсь когда в определенной таблице возникают конфликты, когда 1-ый пользователь открыл первым, 2-ой пользователь позже и оба параллельно выполняют редактирование . Но потом каждый думает что он единственный и вносит свои коррективы и сохраняет. По итогу в базу записывается та версия - кто записал последним. А для другого пользователя потом выявится сюрприз что его работа пропала даром. Чем больше пользователей -тем вероятность конфликтов увеличивается.

Требуется внести правили совместной работы
1) Каждый кто открывает должен выполнить проверку - нет ли блокировки документа (в этой таблице, этой записи)
2) Если блокировки до него не было - то он должен заблокировать документ и приступить к редактированию
3) После редактирования - он сохраняет документ и должен снять блокировку
4) Если документ до него заблокирован - то необходимо получить информацию (кто, когда, с какого компа) и сообщить опоздавшему претенденту
5) Если документ заблокирован - то вывести его в режиме чтения


Таким образом возникает ряд функций
1) Функция проверки на блокировку документа (зная таблицу и № записи)
2) Функция блокировки документа
3) Функция разблокировки документа
4) Запуск документа в режиме редактирования (+ доступ для этого пользователя)
5) Запуск документа в режиме чтения


Но тут требуется 2 параметра:
1) Флаг блокировки FLAG_BLOCK Bit
2) Информация о блокирующем (кто, когда, с какого компа) NAME_BLOCK char(100)

Самый простой и неправильный вариант решения - это добавить в таблицу только одно поле NAME_BLOCK
- То есть чтобы понять есть ли сейчас блокировка SELECT COUNT(NAME_BLOCK) FROM Table1 WHERE LEN(NAME_BLOCK)>0 and ID=123
- Чтобы понять кто заблокировал SELECT NAME_BLOCK FROM Table1 WHERE ID=123
- Чтобы заблокировать UPDATE Table1 SET NAME_BLOCK='Юзер 1 Время ххххх' WHERE ID=123
- Чтобы снять блокировку UPDATE Table1 SET NAME_BLOCK=SPACE(0) WHERE ID=123
- Чтобы получить список всех заблокированных документов SELECT NAME_BLOCK FROM Table1 WHERE LEN(NAME_BLOCK)>0

Гениально работает! Просто и надежно!

Одна проблема - как только пользователь отключается от базы данных - то такая блокировка остаётся навсегда,
так как пользователь думает что он все сделал, а другие думаю что еще работает.



Исправлено 1 раз(а). Последнее : shumik73, 17.04.24 22:38
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
shumik73

Сообщений: 554
Откуда: Алматы
Дата регистрации: 10.05.2006
Так как таблица TABLE1 хранит данные, то она не готова к тому что пользователь может в любой момент отвалиться и не успеть снять блокировку
В SQL Server для этих целей существует динамическое представление sys.dm_tran_locks. Оно возвращает сведения об активных в данный момент в SQL Server ресурсах диспетчера блокировок.

--+-------------------------------------+
--| Просмотр таблицы dm_tran_locks |
--| Request_mode = 'X' если 'Exclusive' |
--| Request_mode = 'S' если 'Shared' |
--| Request_mode = 'U' eсли ...
--+-------------------------------------+
SELECT request_type as App,
resource_description as resource_name,
Request_mode as lock_mode,
request_owner_type as lock_owner,
*
FROM [master].[sys].[dm_tran_locks]
WHERE [master].[sys].[dm_tran_locks].resource_type='APPLICATION'
and [master].[sys].[dm_tran_locks].resource_description LIKE '%[Form1]%'

Особенности этой таблицы в том что - она хранит только те блокировки, которые были сделаны пользователем в то время пока он был подключен к базе
И пока он еще на связи - таблица действует и сообщает всем другим пользователям что этот 1=ый пользователь успел заблокировать.
Стоит ему отключиться от базы - то все его блокировки исчезают. Можно в этом убедиться - если подключиться от разных пользователей и проверять эту таблицу
Очень напоминает разницу между CREATE TABLE Table1 () и созданием курсора CREATE CURSOR Table1 ()
При просмотре можно понять сколько и каких блокировок сейчас действует

Но есть маленькое неудобство - все что можно информативно внести: Описание ресурса в поле resource_description nvarchar(256)
Как видно это поле и так перегружено данными 0:[Form1]6d7d48c5), то что будете записывать пользователь занесено в [Form1]
В этом поле ресурсов - необходимо занести уникальную идентификацию того документа, с которым будут работать пользователи.
То есть надо как-то обозначить таблицу и номер записи. В каком это будет формате - тут дело вкуса
Далее вместо этого будет фигурировать - Form1

Ссылки:
learn.microsoft.com
infostart.ru



Исправлено 1 раз(а). Последнее : shumik73, 17.04.24 23:39
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
shumik73

Сообщений: 554
Откуда: Алматы
Дата регистрации: 10.05.2006
В этой таблице dm_tran_locks будут записываться блокировки. Теперь необходимо реализовать остальные функции: как определить есть ли блокировка на интересующий нас документ

--+---------------------------------------------------------------------------------------------+
--| Функция APPLOCK_MODE |
--| Эта функция возвращает режим блокировки,
--| полученный владельцем блокировки на конкретный ресурс приложения.
--| параметры: |
--| database_principal - пользователь, роль кому дан доступ |
--| (database_principal='public', 'dbo' , 'db_owner') |
--| resource_name - уникальный ресурс - тип nvarchar(255) |
--| lock_owner - Владелец блокировки - тип nvarchar(32) |
--| ('Transaction' (по умолчанию) или 'Session'. |
--| ответ - тип nvarchar(32): |
--| NoLock,Update,SharedIntentExclusive,IntentShared, |
--| IntentExclusive,UpdateIntentExclusive,Shared,Монопольно |
--+---------------------------------------------------------------------------------------------+
BEGIN TRANSACTION;
SELECT APPLOCK_MODE('public', 'Form1', 'Transaction')
COMMIT TRANSACTION; -- ROLLBACK TRANSACTION;
SELECT APPLOCK_MODE('public', 'Form1', 'Session')
-- NoLock запись не блокирована
Ссылка: learn.microsoft.com


--+---------------------------------------------------------------------------------------------+
--| Функция APPLOCK_TEST |
--| может ли быть предоставлена блокировка конкретного ресурса приложения |
--| для указанного владельца блокировки без запроса на блокировку? |
--| параметры: |
--| database_principal - пользователь, роль кому дан доступ |
--| (database_principal='public', 'dbo' , 'db_owner') |
--| resource_name - уникальный ресурс - тип nvarchar(255) |
--| lock_mode - режим блокировки - тип nvarchar(32) |
--| ('Shared', 'Update', 'IntentShared', 'IntentExclusive', 'Exclusive' |
--| lock_owner - Владелец блокировки - тип nvarchar(32) |
--| ('Transaction' (по умолчанию) или 'Session'. |
--| ответ - тип smallint: |
--| 0 - когда блокировка не может быть предоставлена указанному владельцу |
--| 1 - если блокировка может быть предоставлена. |
--+---------------------------------------------------------------------------------------------+
BEGIN TRANSACTION;
SELECT APPLOCK_TEST('public', 'Form1', 'Shared', 'Transaction');
COMMIT TRANSACTION; -- ROLLBACK TRANSACTION;
SELECT APPLOCK_TEST('public', 'Form1', 'Shared', 'Session');
SELECT APPLOCK_TEST('public', 'Form1', 'Exclusive', 'Session');
-- 1 - запись не блокирована, можно блокировать
-- 0 - запись уже заблокирована, блокировать не получится

Ссылка: learn.microsoft.com

Теперь как решить задачу блокировки документа - точнее как в таблицу блокировок добавить информацию о блокируемом документе
после этого можно приступать к редактированию документа

--+---------------------------------------------------------------------------------------------+
--| sp_getapplock
--| Блокировка - Размещает блокировку на ресурсе приложения.
--| параметры: |
--| resource_name - уникальный ресурс - тип nvarchar(255) |
--| lock_mode - режим блокировки - тип nvarchar(32) |
--| ('Shared', 'Update', 'IntentShared', 'IntentExclusive', 'Exclusive' |
--| lock_mode - режим блокировки - тип nvarchar(32) |
--| ('Shared', 'Update', 'IntentShared', 'IntentExclusive', 'Exclusive' |
--| LockTimeout - Значение времени ожидания блокировки (в миллисекундах) |
--| Значение -1 (по умолчанию) |
--| database_principal - пользователь, роль кому дан доступ |
--| (database_principal='public', 'dbo' , 'db_owner') |
--| ответ - тип smallint: |
--| 0 - Блокировка была успешно предоставлена |
--+---------------------------------------------------------------------------------------------+
DECLARE @result int
EXECUTE @result = [master].[sys].[sp_getapplock]
@Resource='Form2',
@LockMode='Exclusive',
@LockOwner='Session',
@LockTimeout=-1,
@DbPrincipal = 'public'
IF @result=0 SELECT 'Блокировка была успешно предоставлена в синхронном режиме.'
IF @result=1 SELECT 'Блокировка была предоставлена успешно после снятия других несовместимых блокировок.'
IF @result=-1 SELECT 'Истекло время ожидания запроса блокировки.'
IF @result=-2 SELECT 'Запрос блокировки был отменен.'
IF @result=-3 SELECT 'Запрос блокировки был выбран как жертва взаимоблокировки.'
IF @result=-999 SELECT 'Указывает ошибку при проверке параметра или другую ошибку вызова.'

Ссылка learn.microsoft.com

После того как внесены изменения и документ сохранен - необходимо убрать блокировку

--+---------------------------------------------------------------------------------------------+
--| Снимает блокировку |
--|Снимает блокировку ресурса приложения. |
--| параметры: |
--| resource_name - уникальный ресурс - тип nvarchar(255) |
--| lock_owner - Владелец блокировки - тип nvarchar(32) |
--| ('Transaction' (по умолчанию) или 'Session'. |
--| database_principal - пользователь, роль кому дан доступ |
--| (database_principal='public', 'dbo' , 'db_owner') |
--| ответ - тип smallint: |
--| 0 Блокировка успешно снята. |
--| -999 Сигнализирует об ошибке проверки параметра или о другой ошибке вызова процедуры.|
--+---------------------------------------------------------------------------------------------+
DECLARE @result int
EXECUTE @result = [master].[sys].[sp_releaseapplock] @Resource='Form1', @LockOwner='Session',@DbPrincipal = 'public'
--EXECUTE @result = [master].[sys].[sp_releaseapplock] @Resource='Form1', @LockOwner='Session',@DbPrincipal = 'dbo'
IF @result=0
SELECT 'Блокировка успешно снята';
ELSE
SELECT @result;
BEGIN TRANSACTION;
DECLARE @result int
EXEC @result = sp_releaseapplock @Resource = 'Form1';
COMMIT TRANSACTION; -- ROLLBACK TRANSACTION;

Ссылка learn.microsoft.com

Следует отметить что по умолчанию lock_owner = 'Transaction' и все команды где этот параметр пропущен или указан должны формироваться в следующем виде:

BEGIN TRANSACTION;
DECLARE @result int;
EXEC @result = ххххххххххх @Resource = 'Form1', @LockOwner='Transaction';
IF @result = -хххх
BEGIN
ROLLBACK TRANSACTION;
END
ELSE
BEGIN
COMMIT TRANSACTION;
END;

Если выбрать @LockOwner='Session' то проще

Что касается контроля за блокировками то в инете можно на найти SQL-запросы которые помогут отследить кто и что блокирует



Исправлено 1 раз(а). Последнее : shumik73, 17.04.24 23:46
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
of63

Сообщений: 26041
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> Программа многопользовательская и логично возникла задача запретить одновременное редактирование файла несколькими пользователями.
Какие тут могут быть решения?

Решение простое - надо (или не надо ?) показать пользователю, что когда он открыл "запись" (за ней стоит много записей в подчиненных таблица, возможно) на желаемый режим "редактирование", то дай ему понять, что эта же "запись" редактируется кем-то другим (красный баннер на экране, всякие сигналы...) если "секретность" не предполагает такой сигнализации (о уже блокировании), то внутренний флаг взведи в программе, что вот такая особая ситуация с записью

Под словом "запись" это совсем не транзакция, а может, "семафор" - искусственная конструкция для блокирования чего либо...
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
shumik73

Сообщений: 554
Откуда: Алматы
Дата регистрации: 10.05.2006
PaulWist
Ну, ни кто не мешает в имя ресурса запихать "что-то полезное", например ID таблички и время начала блокировки Прилржения.
DECLARE
@result int,
@Resource nvarchar(255) = 'Редактируется файл ' + convert(varchar(20), getdate(), 104);
EXEC @result = sp_getapplock @Resource , @LockOwner= 'Session', @LockMode = 'Exclusive';
select * from sys.dm_tran_locks where resource_type = N'APPLICATION' and resource_description like '%Редактируется файл%'

Можно поподробнее развернуть вот это "что-то полезное" ?
Пусть 1 пользователь редактирует табличку с ID=100, то есть он блокирует и в ресурсе указывает 'Редактируется файл 100, 20 апреля 10 часов'
Пользователь 2 тоже хочет редактировать туже табличку и тоже хочет заблокировать с своим ресурсом 'Редактируется файл 100, 20 апреля 11 часов'
И sp_getapplock ему одобрит блокировку того же ID=100, так как имена ресурсов то у них разные.
Поэтому в ресурс нужно включить идентификатор, который был бы один для всех и дату включать не надо

lili
Как-то все это "не очень" удобно для юзеров.
По-хорошему, юзеру должно быть видно, кто и во сколько занял файл на редактирование.
И с этим согласен. Если пользователь 2 не сможет получить заблокировать (получить доступ) - то конечно он захочет узнать кто его опередил.

Следовательно нужно зная имя ресурса - найти (имя, время, компьютер) другого пользователь №1 ?
Эту полезную информацию нужно куда-то записать и найти?
Допустим все это запишем как ресурс и его можно найти в таблицах и вьюхах (в зависимости от версии MSSQL):

Например как выглядет "OBJ=2137;REC=2464" в
exec sp_lock в поле resource "OBJ=b49a3735"
select * from syslockinfo в поле src_text, src_bin "0x000A08004F0042004A003D00B49A3735"
select * dm_tran_locks "0:[OBJ=2137;REC=2464]e1ae8abc)"

Так что записать ресурс легко, да вот найти его и тем более найти его автора прям задача :doom:
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
of63

Сообщений: 26041
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Что за проблемма, найти придумать имя блокируемого ресурса, ну хоть SYS(2007, имя блокирующей программы + ID блокируемой записи) примерно подойдет...

Т.е, блокируемое ... значение, выражения, похожее на "индекс" в фокс...

() фривольно - чтобы заблокировать доступ к собственной жене, например, то нужно указать какие ее параметры... )



Исправлено 1 раз(а). Последнее : of63, 23.04.24 00:23
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
PaulWist

Сообщений: 14761
Дата регистрации: 01.04.2004
shumik73
PaulWist
Ну, ни кто не мешает в имя ресурса запихать "что-то полезное", например ID таблички и время начала блокировки Прилржения.
DECLARE
@result int,
@Resource nvarchar(255) = 'Редактируется файл ' + convert(varchar(20), getdate(), 104);
EXEC @result = sp_getapplock @Resource , @LockOwner= 'Session', @LockMode = 'Exclusive';
select * from sys.dm_tran_locks where resource_type = N'APPLICATION' and resource_description like '%Редактируется файл%'

Можно поподробнее развернуть вот это "что-то полезное" ?
Пусть 1 пользователь редактирует табличку с ID=100, то есть он блокирует и в ресурсе указывает 'Редактируется файл 100, 20 апреля 10 часов'
Пользователь 2 тоже хочет редактировать туже табличку и тоже хочет заблокировать с своим ресурсом 'Редактируется файл 100, 20 апреля 11 часов'
И sp_getapplock ему одобрит блокировку того же ID=100, так как имена ресурсов то у них разные.
Поэтому в ресурс нужно включить идентификатор, который был бы один для всех и дату включать не надо


Репро-код запусти.

select * from sys.dm_tran_locks where resource_type = N'APPLICATION'

вернёт блокировки приложения.

Володя Максимов уже "разжевал" возможные варианты.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
shumik73

Сообщений: 554
Откуда: Алматы
Дата регистрации: 10.05.2006
Как блокировать и разблокировать - тут проблем нет, так как для этого нужен уникальный ресурс!
1) ну хоть SYS(2007, имя блокирующей программы + ID блокируемой записи)
2) например ID таблички и время начала блокировки Прилржения.

select * from sys.dm_tran_locks where resource_type = N'APPLICATION' вернёт блокировки приложения. А точнее список уникальных ресурсов которые в данный момент заблокированы.
Вопрос то в том кто из пользователей это сделал?
Если включить в ресурс IDuser=123 то ресурс уже не будет уникальным так как блокирующий знает, а пытающийся разблокировать нет и вся система блокировки не имеет смысла

Об этом проблеме и речь:
lili
По-хорошему, юзеру должно быть видно, кто и во сколько занял файл на редактирование.

of63
() фривольно - чтобы заблокировать доступ к собственной жене, например, то нужно указать какие ее параметры... )
Если не заблокировать доступ к жене - то как найти того кто провел транзакцию?
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
PaulWist

Сообщений: 14761
Дата регистрации: 01.04.2004
shumik73
select * from sys.dm_tran_locks where resource_type = N'APPLICATION' вернёт блокировки приложения. А точнее список уникальных ресурсов которые в данный момент заблокированы.
Вопрос то в том кто из пользователей это сделал?
Если включить в ресурс IDuser=123 то ресурс уже не будет уникальным так как блокирующий знает, а пытающийся разблокировать нет и вся система блокировки не имеет смысла

Добавь в Resource имя и ID таблички, положи хоть в xml-формате.

Второй знает к какой таблице и ID обращается, дальше написать resource_description like '%Test.id=2%' и распарсить полученную строку, всего делов-то.

Или в чём трудность??

use tempdb
go
create table #test (id int, Name varchar(10))
insert into #test values (1, 'One'), (2, 'Two')
go
DECLARE
@result int,
@Resource nvarchar(255) = (select N'Test.id=' + cast(#test.id as nvarchar(10)) + N' IDuser=Вася Пупки' from #test where id = 2)
EXEC @result = sp_getapplock @Resource ,
@LockOwner= 'Session',
@LockMode = 'Exclusive';
select * from sys.dm_tran_locks where resource_type = N'APPLICATION' and resource_description like '%Test.id=2%'
SELECT APPLOCK_MODE('public', 'Test.id=2 IDuser=Вася Пупки', 'Session');


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 1 раз(а). Последнее : PaulWist, 23.04.24 11:18
Ratings: 0 negative/0 positive
Re: Запрет одновременного редактирования файла
of63

Сообщений: 26041
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
shumik73
Как блокировать и разблокировать - тут проблем нет, так как для этого нужен уникальный ресурс!
1) ну хоть SYS(2007, имя блокирующей программы + ID блокируемой записи)
2) например ID таблички и время начала блокировки Прилржения.

select * from sys.dm_tran_locks where resource_type = N'APPLICATION' вернёт блокировки приложения. А точнее список уникальных ресурсов которые в данный момент заблокированы.
Вопрос то в том кто из пользователей это сделал?
Если включить в ресурс IDuser=123 то ресурс уже не будет уникальным так как блокирующий знает, а пытающийся разблокировать нет и вся система блокировки не имеет смысла

Об этом проблеме и речь:
lili
По-хорошему, юзеру должно быть видно, кто и во сколько занял файл на редактирование.

of63
() фривольно - чтобы заблокировать доступ к собственной жене, например, то нужно указать какие ее параметры... )
Если не заблокировать доступ к жене - то как найти того кто провел транзакцию?

() Мтк, обсуждение касается ПРОГРАММНО обустроенного ограничения доступа к какой-то табличке, или ко всей базе (набору табличек). Если доступ осуществляется только через программу, сделанную специально для доступа к этим табличкам, то можно сделать всё как угодно удобно доступно/недоступно, или, если к таблице "лазят" другими способами (например, фоксовые таблички можно открывать фоксовым же IDE, или "DBFread" каким-нибудь... ХЕКС-редактором/смотрителем.), тогда доступ осуществлять надо совсем по-другому, тем более узнавать "кто пытался открыть файл"...
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 38 (Гостей: 38)

© 2000-2025 Fox Club 
Яндекс.Метрика