Обычная часть логики программирования, которую я часто реализую, похожа на следующий псевдокод:
Let X = some value
Let Database = some external Database handle
if !Database.contains(X):
SomeCalculation()
Database.insert(X)
Однако в многопоточной программе у нас есть условие гонки. Поток A может проверить, находится ли X
в Database
, обнаружить, что это не так, и затем перейти к вызову SomeCalculation()
. Тем временем поток B также проверит, находится ли X
в Database
, обнаружит, что это не так, и вставит дублирующую запись.
Так что, конечно, это нужно синхронизировать как:
Let X = some value
Let Database = some external Database handle
LockMutex()
if !Database.contains(X):
SomeCalculation()
Database.insert(X)
UnlockMutex()
Это нормально, за исключением того, что если приложение является распределенным приложением, работающим на нескольких компьютерах, каждый из которых взаимодействует с одним и тем же внутренним компьютером базы данных? В этом случае Mutex бесполезен, потому что он синхронизирует только один экземпляр приложения с другими локальными потоками. Чтобы это работало, нам понадобится некая «глобальная» техника распределенной синхронизации. (Предположим, что просто запретить дубликаты в Database
- неосуществимая стратегия.)
В целом, каковы некоторые практические решения этой проблемы?
Я понимаю, что этот вопрос очень универсальный , но я не хочу делать этот вопрос для конкретного языка, потому что это проблема, которая возникает на разных языках и в нескольких технологиях баз данных.
Я намеренно избегал указывать, говорю ли я о СУБД или базе данных SQL, а не о чем-то вроде базы данных NoSQL, потому что снова - я ищу обобщенных ответов , основанных на отраслевых практиках. Например, может ли эта ситуация разрешить хранимые процедуры Atomic? Или атомарные транзакции? Или это что-то вроде «распределенного мьютекса»? Или, в более общем плане, эта проблема обычно решается системой базы данных, или она должна решаться самим приложением?
Если окажется, что на этот вопрос невозможно ответить вообще без дополнительной информации, пожалуйста, сообщите мне, чтобы я мог изменить его.