Термины, которые необходимо исследовать на стороне базы данных, это «уровень изоляции транзакций» и «контроль параллелизма».Поддержка платформы СУБД варьируется.Некоторые платформы реализуют подмножество уровней изоляции, определенных в стандартах SQL.(Стандарты SQL позволяют это. Они написаны с точки зрения того, какое поведение недопустимо.) И разные платформы по-разному подходят к управлению параллелизмом.
Википедия, хотя и не авторитетная, имеет хорошее введение в уровни изоляции , а также хорошее введение в контроль параллелизма .
Насколько я знаю, нет никакого способа гарантировать, что один SQL-запрос будет завершаться раньше другого при вызове из разных потоков.
Это своего рода правда.Это также отчасти не соответствует действительности.В стандартах SQL уровни изоляции транзакций не имеют отношения к тому, кто финиширует первым.Они обеспокоены поведением, которое не разрешено.
грязное чтение : транзакция A может считывать данные, записанные параллельной незафиксированной транзакцией B.
неповторяемое чтение : транзакция A считывает данные дважды.Параллельная транзакция, B, фиксирует между двумя чтениями.Транзакция данных, прочитанная первой, отличается от данных, которые она прочитала второй, из-за транзакции B. (Некоторые люди описывают транзакцию A как «одинаковые строки, разные значения столбцов».)
фантомное чтение : транзакция A читает данные дважды.Параллельная транзакция, B, фиксирует между двумя чтениями.Два чтения транзакции A возвращают два разных набора строк, поскольку транзакция B повлияла на оценку предложения WHERE транзакции A.(Некоторые люди описывают транзакцию A как «одинаковые значения столбца, разные строки».)
Вы управляете поведением транзакции в SQL с помощью SET TRANSACTION
.Таким образом, SET TRANSACTION SERIALIZABLE
означает, что грязное чтение, неповторяемое чтение и фантомное чтение невозможны.SET TRANSACTION REPEATABLE READ
разрешает фантомное чтение, но грязное чтение и повторение невозможно.
Вам нужно будет проверить документацию вашей платформы, чтобы узнать, что она поддерживает.Например, PostgreSQL синтаксически поддерживает все четыре уровня изоляции.Но внутренне он имеет только два уровня: чтение зафиксировано и сериализуемо.Это означает, что вы можете SET TRANSACTION READ UNCOMMITTED
, но вы получите поведение «прочитано зафиксировано».
Важно для вас : эффект сериализуемого уровня изоляции состоит в том, чтобы гарантировать, что транзакции, по-видимому, имеютвыдан по одному клиенту.Но это не совсем то же самое, что сказать, что если транзакция A начинается до транзакции B, она будет зафиксирована до транзакции B. Если они не влияют друг на друга, dbms разрешается сначала зафиксировать транзакцию B, не нарушая семантику сериализуемого уровня изоляции..
Когда у меня возникают вопросы о том, как они работают, я проверяю их, открывая два клиента командной строки, подключенных к одной и той же базе данных.