Может ли транзакция SQL блокировать строки только из указанного представления - PullRequest
0 голосов
/ 06 января 2011

В мультитенантном приложении у меня есть таблица со столбцом TenantId. Доступ к этой таблице возможен только с помощью представления, которое выбирает строки, принадлежащие одному арендатору, используя TenantId, хранящийся в CONTEXT_INFO. Есть ли способ иметь транзакции, блокирующие только данные, которые это представление возвращает для определенного арендатора (т. Е. Блокировать только строки с тем же идентификатором TenantId)?

Будет потеря производительности, если я заблокирую всю таблицу, когда я уверен, что вставляемые / обновляемые / удаляемые данные никогда не столкнутся с теми, которые имеют другое значение в столбце TenantId.

Тот же шаблон будет применяться для любого другого представления, которое ограничивает некоторые строки таблицы с помощью предложения WHERE.

1 Ответ

4 голосов
/ 06 января 2011

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

Если вы следуете этому простому правилу, то, учитывая, что каждый отдельный запрос должен добавить предикат TenantId=@currentTenantId, ни один запрос не будеткогда-либо «удивлялся» за пределами среза данных клиента в любой таблице.Это гарантирует, что между двумя арендаторами никогда не будет разногласий, поскольку каждый из них интересуется только своей частью индекса.

Каким-то похожим решением может быть достигнуто использование разбиения на TenantId, но с учетом текущегоОграничение в 1000 секций и снижение производительности, присущее секционированным таблицам, я бы гораздо сильнее предпочел решение с индексным ключом.

Есть такая вещь, которая нарушает это «статус-кво», как эскалация блокировки (которую можно явно отключить с помощью ALTER TABLE SET LOCK_ESCALATION) или блокировка таблицы массовой загрузки (отключается с помощью sp_tabeloption).

Итак, имея это знание, мы можем вернуться к вашему вопросу и сформулировать его следующим образом:Можем ли мы обеспечить изоляцию, чтобы арендатор никогда не блокировал ресурсы, принадлежащие другому арендатору? ».Ответ - да, если вы гарантируете, что в наборе строк каждый есть соответствующие пути доступа для конкретного арендатора.Что в точности соответствует тому, что я говорю в первом абзаце: добавьте TenantId в качестве крайнего левого ключа к каждому индексу, включая все кластеризованные, и не используйте кучи.Мелкий шрифт будет означать, что решение будет работать в большинстве случаев, но всегда будут определенные сценарии, в которых арендатор может заблокировать ресурсы, принадлежащие другому арендатору.Но для лучшей изоляции вам потребуется один дБ на каждого арендатора, что является кошмаром для развертывания / обслуживания / обновления.

...