Как заблокировать строку стола - PullRequest
2 голосов
/ 02 февраля 2009

У меня есть приложение, которое работает на терминале.

Терминал зарегистрирован в таблице базы данных.

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

Каков наилучший способ сделать это?

Я использую C # .NET в качестве языка программирования и SQL Server в качестве СУБД.

Спасибо: D

Ответы [ 4 ]

4 голосов
/ 02 февраля 2009

В общем, я стараюсь работать с кратковременными блокировками, где я могу выполнить целую единицу работы за одну (сериализуемую) транзакцию; это устраняет необходимость в дополнительном механизме блокировки, так как блокировки db сделают все необходимое.

При работе с долговечными замками: Для этой цели плохая идея использовать rdbms-блокировки - она ​​просто не масштабируется. Столбцы с метками времени или версиями строк являются хорошим способом обеспечения оптимистичного параллелизма для предотвращения случайного перезаписи.

Чтобы опубликовать / применить тот факт, что строка редактируется, я бы сохранил идентификатор пользователя / имя пользователя блокирующего пользователя в столбце (ноль, если не заблокирован). Это позволяет понять, кому принадлежит строка, т. Е. Когда вы хотите отредактировать строку, сначала обновите ее, установив свой идентификатор пользователя (и убедитесь, что он еще не заблокирован).

Чтобы справиться с некорректно снятыми замками (из-за неисправного терминала и т. Д.), Есть 3 распространенных варианта:

  • когда владелец замка снова входит в систему, разрешить ему взломать свои собственные блокировки
  • разрешить администратору взломать блокировки пользователя
  • сохранить столбец тайм-аута блокировки (datetime) и назначить запланированное задание, чтобы автоматически разблокировать просроченные строки

Итак, подведем итог - рассмотрим что-то вроде:

Foo
===
Id | ...data... | Timestamp | LockOwner | LockTimeout
---+------------+-----------+-----------+------------

и т.д.

0 голосов
/ 02 февраля 2009

Самый простой способ сделать это - предположить, что у вас есть совместные процессы, и приложение терминала (которое, я предполагаю, создает строку) генерирует и сохраняет уникальное значение, связанное с этим терминалом, при создании строки. Таким образом, каждый процесс, который вставляет строку в таблицу, имеет свое уникальное значение и может использовать это значение в качестве проверки при обновлении строк в таблице. База данных может генерировать уникальное значение для вас (Guid или UniqueIdentifier или даже просто поле целочисленного идентификатора), если вы выполняете вставку и считываете вставленное значение обратно в транзакцию.

0 голосов
/ 02 февраля 2009

во многих sql диалектах вы можете сделать такой вид блокировки:

begin transaction

select * from FOOTABLE f for update where ID = '12345'

[... do any other stuff here ... ] 

commit transaction
0 голосов
/ 02 февраля 2009

Базы данных не работают для этого вида блокировки. Вы можете заблокировать элементы, но это только на время операции (SELECT, INSERT, UPDATE, DELETE).

Возможно, вам следует попробовать добавить битовый столбец с именем "inUse" и установить для него значение True (1), когда терминал его использует. Запрограммируйте терминалы на соблюдение значения inUse, если оно уже установлено, и убедитесь, что оно установлено в False (0), когда терминал завершен.

Почему строка должна быть заблокирована в любом случае, не лучше ли иметь строку для каждого терминала?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...