Интересует, существуют ли и какие методы синхронизации на уровне БД. Например, нужно для такой задачи. Есть приложение, которое может быть запущено в нескольких экземплярах на разных машинах. Приложение ищет свободное время для ресурса, чтобы занять его. Соответственно может быть проблема когда 2 или более экземпляра приложения почти одновременно считают из базы, что ресурс с 13 до 14 часов свободен и займут его. Соответственно, получится так, что один и тот же ресурс занят в одно и тоже время для разных операций, что недопустимо.
Есть пару идей:
— например занимать ресурс с 13 до 14, если тот свободен, а потом делать проверку по факту, не получилось ли так что ресурс заняли двое и если так, то удалять свою отметку о том что ресурс занят. Но вариант не очень подходит, так как не факт, что приложение не умрет до того как определит, что ресурс уже занят и нужно снимать свою отметку.
— или можно сделать например таблицу, в которую писать, что ресурс находится в монопольном режиме и его пока нельзя трогать. Соответственно, можно эту отметку поставить и потом занимать ресурс. Хотя опять же, как убедиться, что несколько приложений не поставят эту отметку одновремено и как потом быть уверенным, что приложение не умрет до того как эту отметку уберет.
Наверное, такой проблемой уже интересовались и есть какие-то решения.
Здравствуйте, Аноним, Вы писали:
А> Интересует, существуют ли и какие методы синхронизации на уровне БД. Например, нужно для такой задачи. Есть приложение, которое может быть запущено в нескольких экземплярах на разных машинах. Приложение ищет свободное время для ресурса, чтобы занять его. Соответственно может быть проблема когда 2 или более экземпляра приложения почти одновременно считают из базы, что ресурс с 13 до 14 часов свободен и займут его. Соответственно, получится так, что один и тот же ресурс занят в одно и тоже время для разных операций, что недопустимо.
например, можно проверку (на практике — повтор проверки) ресурса на доступность делать после его блокировки.
пример для MS SQL Server (псевдокод):
select @success = 0
if exists (select 1 from resources r where resource_id = @id and is_available = 1) -- #1
begin
begin transaction
if exists (select 1 from resources (tablockx holdlock) where resource_id = @id and is_available = 1) -- #2
begin
update resources set is_available = 0 where resource_id = @id
select @success = 1
commit transaction
end
else
rollback transaction
end