Разделы
Публикации
Популярные
Новые
|
Главная » Оптимизация производительности transact 1 ... 27 28 29 30 31 32 33 ... 55 се: Zbs:: \ .о innes ;5 rcw(5 ; affec!.ed) 5.:-/ег: Иьд b~i. Level 16. SiaLe 1. i.-ne i DC.ITr steiener.t conflcied with COLUMN RtrERCNCr ccnstraim F\ :,u eauth au C 16528:. Tne conflict occurrec n catstase putt. tarJe fteauthor. column au ic. au Inart au fna.Tie Ee.nret Aoraham Blotchet-HalIs Reginald Cai-son Creryl DeFrance Michel de: Castillo Innes (5 row(s) affectec) Оператор PRINT никогда не будет выполнен, потому что нарушение ограничения, возникшее из-за попытки очистить таблицу authors, прерывает выполпе-пие всего пакета команд (операторов перед GO). II это несмотря на тот факт, что ROLLBACK TRAN на.ходится прямо перед PRINT. Вот поче.му предпочтительнее проверять @@ERROR посте кажд011 мод,нфика-ини данных, а не вк.чючать SET XACT ABORT. Это особенно важно, когда в транзакции вызьшается храии.мая процедура. Если процедура вызовет опшбку во вре.мя выполнения, операторы, следуюпиш за пей в пакете ко.хшпд, не будут выполнены, и, таким об)азо.м, обработать ошибку будет невоз.можно. Уровни изоляции транзакций SQL Server поддерживает четыре уровня изоляции транзакций. Как я упоминал ранее, уровень изоляции определяет, как транзакция влияет на другие транзакции и, соответственно, как они влияют на нее. Нам всегда приходится выбирать между целостностью и возможностью одновременного доступа. Установка более строгого уровня изоляции увеличивает целостность данных ценой доступности. Выбор .менее строгого уровня увеличивает воз.чюжность паратлельного доступа за счет целостности данных. Фокус в то.м, чтобы найти ко.мпромисс между эти-.ми противоречиями так, чтобы были выполнены требования вашего приложения. Для установки уровня изоляции используется ко.манда SET TRANSACTION ISOLATION LEVEL. Допустимые уровни изоляции включают: READ UNCOMMFTTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE. READ UNCOMMITTED Указание READ UNCOMMITTED, no существу, эквивалентно использованию подсказки (hint) NOLOCK для каждой таблицы, задействованной в транзакции. Этот уровень наи.менее запретительный из четырех уровней изоляции SQL Server. Он позволяет осуществлять грязное чтение (чтение незафиксированных из- менений другими транзакциями) и неповторяющееся чтение (то есть когда данные могут изменяться между чтениями в транзакции). Чтобы увидеть, как READ UNCOMMITTED позволяет грязное и неповторяющееся чтение, запустите одновременно следующие запросы: -- Query 1 SELECT TOP 5 titlejd. qty FROM sales ORDER BY t1tle id. stor id BEGIN TRAN UPDATE sales SET qty=0 SELECT TOP 5 titlejd. qty FROM sales ORDER BY title id. stor id WAITFOR DELAY 00:00:05 ROLLBACK TRAN SELECT TOP 5 title id. qty FROM sales ORDER BY titlejd. stor id -- Query 2 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED PRINT Теперь вы это видите... SELECT TOP 5 title id. qty FROM sales WHERE qty=0 ORDER BY title 1d. storjd IF (3(aR0WC0UNT>0 BEGIN WAITFOR DELAY 00:00:05 PRINT ...a теперь нет' SELECT TOP 5 title id. qty FROM sales WHERE qty=0 ORDER BY t1tle id. storjd Сейчас вы это видите... title id qty BU1032 О BU1032 О BU1032 О BUllll О BU2075 О (5 row(s) affected) ...а тепперь нет title id qty (О row(s) affected) Пока выполняется первый запрос (у вас есть пять секунд), запустите второй, и вы увидите, что он может получить доступ к незафиксированным изменениям, внесенным первым запросом. Зате.м второй запрос ждет окончания первой транзакции и пытается прочесть те же самые данные снова. Так изменения были отменены, данные исчезли, оставив второй запрос с неповторяющимся чтением. READ COMMITTED READ COMMTTTED - это уровень изоляции SQL Server по умолчанию, так что если вы не укажете другой, будет использован READ СОММПТЕО. READ COMMITTED не разрешает грязное чтение, накладывая коллективные блокировки (share locks) на данные, с которыми проводится работа, но позволяет изменять эти данные во Уровни изоляции транзакций 311 время траизакции. что может привести к иеиовторяемому чтению и/или фан-толиням данным. Чтобы увидеть, как это работает, выполните однов|)е.\1еиио следуюпще запросы: -- Quer-y ; 5£Г T.RA,\SACTION ISOLAnO:-. l.tVhL KLAD CG-VVUED BEGIN TRAN PRINT Здесь Mb, В.ЯИМ ЗаП;;си ,. SELECI TCP 5 title ia, qty FROM sales CRuER tit:e !a, stor ic! .vAHFCR DELAY 00:00:05 PRINI ,., a здесь уже не; SELECT TCP 5 titlejd, qty FROM saies ORDER BY tille id, stor id GO ROLLBACK TRAN -- Gtery 2 SET TRA,NSACriON ISOLAIION LEVEI READ COMMinEu UPDATE sales SET qty=6 WHERE qty=5 Здесь мы видим записи.,. title id qty BUI 032 5 BU1032 10 BUI 032 30 BUllll 25 BU2075 35 , a здесь уже нет titie 1d qty BUi032 6 BU1032 10 BUi032 30 BUllll 25 BU2075 35 Как и в предыдущем при.мере, запустите первый запрос, зате.м быстро запустите второй (у вас есть пять секунд). В это.м примере значение столбца qty в первой записи таблицы sales из.меняется между чтениями в первом запросе - классический пример неповторяемого чтения. REPEATABLE READ REPEATABLE READ накладывает блокировки, чтобы предотвратить из.менение другими пользователями даины.х, с которы.ми работает транзакция, но не запрещает добавление новых записей, поэто.му .между чтениями в транзакпии возможно возникновение ([анто.мных записей. Вот прп.мер (как и в случае других ири.меров, запустите первый запрос, затем параллельно второй - у вас есть пять секунд, чтобы запустить второй запрос): -- Оиегу 1 SET IRA.NSACTION ISOLATION LEVEL REPEATABLE READ BEGIN TRAN PRINT Брюки превращаются , SELECT TOP 5 t1tle id, qty FROM sales ORDER BY qty WAITFOR DELAY 00;00:05 PRINT ...в элегантные шорты' SELECT ТОР 5 title icl. qty FROM sales ORDER BY qty ROLLBACK TRAN -- Query 2 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ INSERT sales VALUES (6380.9999999.GETDATEC).2.USG-Whenever.PS2091) Брюки превращаются... title id qty PS2091 3 BUI032 5 PS2091 10 MC2222 10 BU1032 10 ... в элегантные шорты title id qty PS2091 2 PS2091 3 BU1032 5 PS2091 10 MC2222 10 Как вы видите, между чтениями таблицы sales появляются новые записи даже при том, что был указан уровень изоляции REPEATABLE READ. Хотя REPEATABLE READ предотвращает изменение данных, к которым уже был получен доступ, данный уровень не предотвращает добавление новых данных; таким образом, возможно появление фантомных записей. SERIALIZABLE SERIALIZABLE предотвраП1;ает грязное чтение и появление фанто.мных записей, накладывая серию блокировок на данные. Это наиболее запретитеЛьный уровень из четырех уровней изоляции SQL Server. Указание SERIALIZABLE эквивалентно при.менению подсказки HOLDLOCK для каждой таблицы, используемой в транзакции. Вот пример (удалите запись, которую вы добавили в предыдущем примере, перед те.м как выполнять этот код): -- Query 1 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRAN PRINT У меня в рукаве ничего нет. . SELECT TOP 5 title id. qty FROM sales ORDER BY qty WAITFOR DELAY 00:00:05 PRINT ...И в моей шляпе тоже SELECT TOP 5 title id. qty FROM sales ORDER BY qty ROLLBACK TRAN -- Query 2 BEGIN TRAN SET TRANSACTION ISOLATION LEVEL SERIALIZABLE -- Этот INSERT не будет выполнен, пока не завершится первая транзакция INSERT sales VALUES (6380.9999999.GETDATEO.2.USG-Whenever.PS2091) ROLLBACK TRAN у мен? 3 cyKdie V, пе t1t ie ic Qty ES2C91 3 eU1332 5 PS209: 1С МС2222 1С EU1032 IC ... и в моей л1ЛЯ1 ь I orie title id Qty PS2C91 3 BU1032 5 PS2C91 1С MC2222 10 BUI 032 1С В этом примере блокировки, палол<еииые li резу.тьтате установки уровня нзолящп! SERIALIZABLE, ие дадут вьиюлпиться второ.му запросу, пока не завер-иптгся первый. Хотя это и обеспечивает наибольшую целостность даины.х, она достается nenoii значительного умепьше1пи1 возхюжиости параллельного доступа. Команды для управления транзакциями и их синтаксис Как я сказал ранее, для уп)авления т|)апзакция\и1 в Transact-SQL служат команды BEGIN TRAN, COMMIT TRAN и ROLLBACK TRAN (храни.мые процедуры sp xxxx xact -это устаревптий код, который прн.мепялся в прошло.м в приложениях, использующих двухфазную фиксацию DB-Library, вы пе должны их ири.менять). Точный ситггаксис для начала траизакции такой; BEGIN T(.N[SACTiONj [nameCoTrdnNaineVar] Для фиксации транзакции используйте COMMIT lRAN[SACnONl [nainelPTranNameVar] И для от.меиы траизакции - ROLLBACK TRANISACTION] [nameiPTranNameVdr] Вы также можете при.менить ко.манды COMMIT WORK и ROLLBACK WORK вместо COMMIT TRANSACTION и ROLLBACK TRANSACTION, хотя в них нельзя использовать названия транзакций. Вложенные транзакции Transact-SQL позволяет использовать вложенные транзакции с по.мощью b;io-женных ко.мапд BEGIN TRAN. Для определения уровня вложенности можно задействовать автоматическую пере.менную @@TRANCOUNT: О означает, что вложенности нет, 1 - глубину вложенности, равную единиие, и так далее. Пакеты и храни.мые процедуры, чувствительные к уровню вложенности, должны проверять @@TRANCOUNT при запуске и реагировать соответственно. Хотя на самом деле все не так, как кажется: SQL Server не поддерживает настоящие вложенные транзакции. Команда COMMIT, выполненная для любой транзакции, кроме самой внешней, не запишет никакие изменения на диск - она просто уменьшит на единицу автоматическую переменную @@TRANCOUNT. С другой стороны, ROLLBACK работает независимо от уровня, на котором выполняется, она откатьшает все транзакции, независимо от уровня вложенности. Хотя это может показаться нелогичным, для такого поведения есть очень важные причины. Если бы вложенная команда COMMIT на са.мом деле записала данные на диск, внешняя команда ROLLBACK не смогла бы их от.менить, поскольку они уже зафиксированы. Аналогично, если бы ROLLBACK не от.меняла изменения на всех уровнях, ее вызов из хранимых процедур и триггеров был бы намного сложнее, так как вызывающей стороне пришлось бы проверять возвращенные значения и уровень вложенности транзакции, чтобы определить, необходимо ли отменить незавершенные транзакции. Вот пример, иллюстрирующий некоторые особенности вложенных транзакций: SELECT Before BEGIN TRAN,(aiaTRANCOUNT BEGIN TRAN SELECT After BEGIN TRAN.(3(aTRANC0UNT DELETE sales BEGIN TRAN nested SELECT After BEGIN TRAN nested.PiaTRANCOUNT DELETE titleauthor COMMIT TRAN nested -- Просто уменьшает на единицу MTRancOUNT SELECT After COMMIT TRAN nested.WRANCOUNT GO -- Когда Это возможно, помещайте ROLLBACK TRAN в отдельный пакет, чтобы из-за ошибок в пакете не осталось открытых транзакций ROLLBACK TRAN SELECT After ROLLBACK TRAN.(aPTRANCOUNT SELECT TOP 5 au 1d FROM titleauthor Before BEGIN TRAN 0 After BEGIN TRAN 1 After BEGIN TRAN nested After COMMIT TRAN nested After ROLLBACK TRAN au id 213-46-8915 409-56-7008 267-41-2394 724-80-9391 213-46-8915 В этом примере .\п)1 видим, что, несмотря иа вложенную команду COMMIT TRAN, внешняя ко.манда ROLLBACK все ])ав1ю отменяет действие команды DELETE titleauthor. Вот другой пример вложенньгх rpansaKunii: SELECT Before BEGIN TRAN.@@rRANCOUNT BEGIN IRAN SELECT Afte- BEGIN TRAN.g@TRANCOUNr DELETE sales ELGIN TRAN nested SELECT After BEGIN TRAN nested.@@TRANCOLNГ DELETE titleauthor ROLLBACK TRAN SELECT After ROLLBACK TRAN,P(aTRANCOUNT IE @@IRANCOUNT>C BEGIN COMMIT TRAN -- Эта команда никогда не выполнится из-за ROLLBACK SELECT After COMMIT TRAN,g@TRANCOUNT SELECT fOP 5 au id FROM Litleauthor Before BEGIN TRAN 0 After BEGIN TRAN 1 Atter BEGIN TRAN nested After ROLLBACK TRAN au id 213-46-8915 409-56-7008 267-41-2394 724-80-9391 213-46-8915 В .этом примере вьиюлиение никогда не дойдет до COMMIT TRAN, поскольку ROLLBACK TRAN от.меняет все открытые транзакции и устанавливает @@TRANCOUNT в нуль. Обратите внимание, что мы пе сможем выполнить ROLLBACK для именованной транзакции nested. ROLLBACK может отменить и.менованную транзакцию, только еслтг .это са.мая внешняя транзакция. Попытка откатить эту транзакцию приведет к сообшению: Server: Msg 6401, Level 16, State 1, Line 10 Cannot roll back nested. No transaction or savepoint of that name was found. Несмотря на сообщение об ошибке, проблема не в то.м, что не существует траизакции с указаниы.м и.мене.м. Проблема в том, что ROLLBACK можно использовать для именованной транзакции только в том случае, если она са.мая внешняя. Вот прп.мер, иллюстрирующий пртьменение ROLLBACK TRAN с названия,\н1 транзакций: SELECT Before BEGIN TRAN main.(agTRANCOUNT BEGIN TRAN main SELECT After BEGIN TRAN main.(agTRANCOUNT DELETE sales BEGIN TRAN nested SEtECT After BEGIN TRAN nested.№TRANCOUNT DELETE titleauthor ROLLBACK TRAN main SEtECT After ROLLBACK TRAN main,@@TRANCOUNT IF @@TRANCOUNT>0 BEGIN ROLtBACK TRAN -- Выполнение никогда не дойдет до этого места из-за предыдущей команды ROLLBACK SELECT After ROLI BACK TRAN .lagTRANCOUNT SEtECT TOP 5 au id FROM titleauthor Before BEGIN TRAN main 0 After BEGIN TRAN main 1 After BEGIN TRAN nested 2 After ROLLBACK TRAN main 0 au id 213-46-8915 409-56-7008 267-41-2394 724-80-9391 213-46-8915 В этом примере мы назвали внешнюю транзакцию main , а зате.м использовали ее имя в ROLLBACK TRAN. Заметьте, что ROLLBACK TRAhJ не требует указания Названия транзакции, независимо от того, была ли транзакция инициирована с имени. По этой причине многие разработчики вообще избегают применения названий транзакций с ROLLBACK, так как это не имеет смысла. Это в значительной степени вопрос личного выбора, и все работает хорошо, пока вы понимаете, как это работает. Если только не указана точка сохранения (смотрите далее), ROLLBACK TRAN всегда отменяет все транзакции и устанавливает @@TRANCOUNT в нуль, независимо от контекста, в котором она была вызвана. SAVE TRAN и точки сохранения Вы можете контролировать, какие транзакции отменяет ROLLBACK, с по.мошью команды SAVE TRAN. SAVE TRAN создает точку сохранения, до которой вы можете выполнить отмену, если захотите. Синтаксически вы просто передаете название точки сохранения команде ROLLBACK TRAN. Вот пример: SELECT Before BEGIN TRAN main.?@TRANCOUNT BEGIN TRAN main SELECT After BEGIN TRAN main.OgTRANCOUNT DELETE sales SAVE ;,RAi\ Sa eS - >L MrasTi/idcM ЮНчу LjAPa.-eiul SELECT Afte- SAVE TRAN saies.(?(?:RANCOUNГ -- 3-id4eri/e i=3jRANC0uN re изненилссь BEGIN TRAN rested SELECT After BEGIN TRAN rested.S? ANCCJNT DELETE titled.thor SAVE TRAl titieautiiCr yciandii/iBden очку со/оан'ен/я SELECT After SAVE TRAN ttleautior.?(?TRANCOJNT -- Значение @@TRANCCUNt не изменипось ROLLSACK TRAN sales SELECT After ROLLBACK IRAN sales .C={aIANCCCN -- Знанение (a(?TRANCCUNT не изменилось SELECT TOP 5 aj id FRC. t:tlea.trior IF (a?TRANCOUNT>0 BEGIN ROLLBACK TRAN SELECT After ROLLBACK TRAN ,C*TRAICCLIN SELECI TOP 5 au id FROM tUieautnor Before BEGIN TRAN inain 0 After BEGIN TRAN ir.air 1 After SAVE TRAN sales 1 After BEGIN TRAN nested 2 After SAVE TRAN titleautnor 2 Ater ROLLBACK TRAN sales au id 213-46-8915 409-56-7006 267-41-2394 724-80-9391 213-46-8915 After RCLLBACK. TRAN 0 au id 213-46-8915 409-56-7008 267-41-2394 724-80-9391 213-46-8915 After ROLLBACK TRAN au id 213-46-8915 409-56-7008 267-41-2394 724-80-9391 213-46-8915 Server: Msg 3903. Level 16. State 1. Line 17 The ROLLBACK TRANSACTION request has ПО corresponding BEGIN TRANSACTION. After ROLLBACK TRAN 0 Как и в версии 6.5, SQL Server 7.0 позволяет повторно применить название точки сохранения, но, если вы это делаете, запоминается только последняя точка сохранения. Отмена с использованием названия точки сохранения будет осуществлена до последнего места задействования точки сохранения. Избегайте лишних вызовов ROLLBACK Поскольку ROLLBACK TRAN отменяет все открытые транзакции, важно избегать неосторожных повторных вызовов этой команды. Как только она вызвана один раз, нет необходимости (да и не разрещено) вызывать ее снова, пока не инициирована новая транзакция. Например, рассмотрим следующий код: SELECT Before BEGIN TRAN .№TRANCOUNT BEGIN TRAN SELECT After BEGIN TRAN.(a@TRANCOUNT DELETE sales BEGIN TRAN nested SELECT After BEGIN TRAN nested.@(?TRANCOUNT DELETE titleauthor IF @@ROWCOUNT > 1000 COMMIT TRAN nested ELSE BEGIN ROLLBACK TRAN -- Полностью отменяет обе транзакции SELECT After ROLLBACK TRAN,@@TRANCOUNT SELECT TOP 5 au id FROM titleauthor ROLLBACK TRAN - A здесь произойдет ошибка -- нет транзакций для отката SELECT After ROLLBACK TRAN.@@TRANCOUNT SELECT TOP 5 au id FROM titleauthor Before BEGIN TRAN 0 After BEGIN TRAN 1 After BEGIN TRAN nested 2 1 ... 27 28 29 30 31 32 33 ... 55 |
© 2004-2025 AVTK.RU. Поддержка сайта: +7 495 7950139 в тональном режиме 271761
Копирование материалов разрешено при условии активной ссылки. |