Как уровни изоляции SQL Server работают с представлениями?

У меня есть база данных SQL Server 2012 Set Allow Snapshot Isolation = TRUE. Давайте назовем это DBSnap.

У меня есть другая база Set Allow Snapshot Isolation = FALSEданных . Давайте назовем это DBRead.

ВDBSnap, Я создал представление к таблице в DBREAD(называется то же имя для удобства ссылки):

Create View DBReadTable 
as 
    Select * 
    from DBRead.dbo.DBReadTable.

Если я выполняю следующие команды, они завершаются ошибкой:

set transaction isolation level snapshot

Select * 
from DBRead.dbo.DBReadTable

Ошибка:

Msg 3952, Уровень 16, Состояние 1, Строка 2
Не удалось выполнить транзакцию изоляции моментальных снимков для доступа к базе данных DBRead, поскольку изоляция моментальных снимков в этой базе данных запрещена. Используйте ALTER DATABASE, чтобы разрешить изоляцию моментальных снимков.

Однако если я выполняю эти команды, в основном доступ к таблице в базе данных DBRead образуют представление в DDSnap:

set transaction isolation level snapshot

Select * 
from DBSnap.dbo.DBReadTable

Это работает.

Что на самом деле происходит во втором случае?

Выполняется ли управление версиями строк DBSnapдля таблицы in DBRead(т. е. имеет ли DNSnapпредставление информацию о версии строк)?

Или замок помещается на столе DBRead?

Спасибо!,

Graeme Черный

2 ответа

  1. Я не смог воспроизвести это с моей стороны. Конечно, я выполняю SQL Server 2016 вместо 2012. Я попытался создать представление, как вы предлагали, и получил ту же ошибку, как если бы я запросил базу данных напрямую.

    Msg 3952, Level 16, State 1, Line 2
    Snapshot isolation transaction failed accessing database 'DBRead' because snapshot isolation is not allowed in this database. Use ALTER DATABASE to allow snapshot isolation.
    

    Следующая цитата MSDN, по-видимому, указывает на то, что описанное поведение не должно происходить:

    Если транзакция, использующая уровень изоляции моментальных снимков, обращается к данным в нескольких базах данных, для параметра ALLOW_SNAPSHOT_ISOLATION в каждой базе данных должно быть установлено значение ON.

    (от https://msdn.microsoft.com/en-us/library/ms173763 (v=sql.110).aspx)

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

  2. Мои извинения, мой пост неправильный. Я не понял, что представление, которое я использовал для тестирования, было встроено (NOLOCK) в него, тем самым переопределяя снимок.