SQL Server Как всегда откатить всю транзакцию - PullRequest
1 голос
/ 28 июня 2019

У меня есть несколько необычная потребность в обработке транзакций.

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

Однако у меня есть проблема в том, что пользователи могут кодировать внутри процедур тестирования и могут вызывать rollback transaction, который может быть или не быть внутри (вложенной) транзакции (точка сохранения).

высокий уровень выглядит так

start transaction
initialize test
run test with user code
   may or may not contain:
      - start tran
      - start tran savename
      - commit tran
      - commit tran savename
      - rollback tran
      - rollback tran savename
output testresults
rollback transaction

Есть ли способ убедиться, что я наконец смогу всегда вернуться к исходному состоянию?Я должен учитывать, что пользователи могут вызывать хранимые процедуры / триггеры, которые могут быть вложенными и могут содержать операторы транзакций.Со всеми моими решениями в тот момент, когда пользователь использует откат trans в своем тестовом коде, он избегает транзакции, и не все будет очищено

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

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

Ответы [ 4 ]

0 голосов
/ 29 июня 2019

Я считаю, что на самом деле нужно написать контрольные примеры для T-SQL. Если это правильно, то я чувствую, что вам не нужно изобретать велосипед и начинать использовать тестовую среду с открытым исходным кодом T-SQLT https://tsqlt.org/

0 голосов
/ 28 июня 2019

Я не думаю, что возможно откатить часть транзакции и сохранить другую транзакцию без изменений. В момент отката транзакции происходит откат всей транзакции.

0 голосов
/ 28 июня 2019

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

Я также решил не пройти тест, когда стартующий @@TRANCOUNT и окончание @@ TRANCOUNT не совпадают, поэтому ни один тест не может пройти, если что-то не так с пользовательскими транзакциями.

Однако текущая система все еще будет бороться с пользователем, выполняющим COMMIT TRAN.Это проблема для другого времени.

0 голосов
/ 28 июня 2019

Я не думаю, что это возможно без каких-либо сообщений / правил для кода пользователя.Несмотря на то, что вы делаете, если код пользователя запускает столько COMMIT с, сколько @@TRANCOUNT в то время, транзакция будет зафиксирована, и вы ничего не сможете с этим поделать.

В одну сторонуВы можете сделать это, если вы проверяете / применяете код пользователя, чтобы вместо COMMIT изменить его на if @@TRANCOUNT>=2 COMMIT.Это гарантирует, что ИСТИННАЯ фиксация данных может быть выполнена только ВАШЕЙ COMMIT командой.Конечно, бывает, что вы никогда не хотите коммитить, поэтому вы просто rollback и все кончено.

Вы упоминаете:

Что я хочу, так это если пользователь вызывает откатоткатывается только их часть транзакции

Обратите внимание, что вложенные транзакции являются своего рода мифом.Обратитесь к этой превосходной статье .Короче говоря: «Вложенные» BEGIN TRANSACTION s и COMMIT s на самом деле ничего не делают, кроме изменения значения системной переменной @@TRANCOUNT, так что некоторая организация может быть создана с помощью процедур.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...