У меня есть база данных с основной таблицей (назовем ее владельцем) и несколько вложенных таблиц с запасами (например, автомобили, книги и т. Д.).
Например:
Owner
имеет столбцы: owner_id, name
Cars
имеет столбцы: owner_id (foreign key), brand
Books
имеет столбцы: owner_id (foreign key), title, author
Моя программа должнарассчитать статистику, например Сколько владельцев BMW также владеет книгой о Гарри Поттере , используя различные сторонние библиотеки.Я хочу прочитать все строки из всех таблиц одновременно, а затем выполнить анализ в коде, отличном от SQL.
Я хочу прочитать все таблицы, используя отдельные операторы Select * From X
.Я не могу использовать одно большое соединение, так как оно будет возвращать слишком много строк ((владельцы * автомобили * книги) вместо (владельцы + автомобили + книги)).Union также не сокращает его, поскольку таблицы содержат разные столбцы разных типов.
Я установил
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
, но у меня все равно есть некоторые проблемы.
Если я подчеркиваю базу данных, выполняя два потока, один случайным образом вставляя или удаляя, а другой читая, я иногда получаю противоречивые результаты, например, Cars
были удалены между чтением Owners
и чтением таблицы Cars
.
У меня есть несколько вопросов:
Как правильно предотвратить изменение при чтении из нескольких таблиц по одной?Ни одна таблица не должна быть изменена, пока все не будут прочитаны.
Я использую SQL Server 2005 (в сети) и SQL Server 2005 Express (локальный).Могу ли я явно получить блокировки для нескольких таблиц одновременно?
Если я запускаю свою локальную базу данных SQL Server Express, я не могу заставить ее работать независимо от того, что я делаю.Если я запускаю свою сетевую базу данных SQL Server 2005, я могу заставить ее работать (с некоторыми усилиями).Поддерживает ли SQL Server Express уровень изоляции транзакции SERIALIZABLE?Я считаю, что это должно.Различия могут быть связаны с медленным подключением к сети, но я не знаю.
На моем локальном БД я не могу предотвратить изменения между чтениями.То есть один поток случайно удаляет случайного владельца (сначала автомобили, затем книги, затем владельца) или вставляет нового владельца (введите владельца, вставьте 2 машины, вставьте 2 книги).Другой поток читает с использованием:
Begin Tran
Select owner_id From Owner
Select owner_id, brand From Cars
Select owner_id, title, author From Books
Commit Tran
Независимо от того, что я делаю, иногда я получаю владельца с нулевым количеством автомобилей или нулевым количеством книг.Это никогда не должно происходить, поскольку все вставки и удаления находятся в одной транзакции.Мне кажется, что экспресс-сервер не блокирует операторы Owner, Cars и Books одновременно.
На сетевом SQL Server 2005 он работает нормально, но это может быть из-за медленного соединения и, следовательно, более низкой вероятности.одновременного выполнения.
На моей локальной базе данных я начинаю каждую транзакцию с фиктивного Select
из всех таблиц, чтобы предотвратить взаимоблокировку.Я не понимаю, почему это предотвращает взаимоблокировку, а не модификацию таблиц.В этом нет необходимости в сетевом SQL Server 2005.
В настоящий момент я не могу сказать, неправильно ли я понял что-то об изоляции транзакции или проблема в различиях между SQLServer Express и SQL Server 2005. Любая помощь или идеи будут с благодарностью.