Sql-Server

在回滾的事務中仍會發生哪些事件?

  • November 18, 2019

當它們所屬的事務被回滾時,所有數據修改都被撤消是真的嗎?

例如,如果一個游標剛剛執行了 100 次儲存過程並在每次迭代中更新了一個表,那麼所有這些更新都會回滾嗎?

DDL 語句會回滾嗎?…例如 DROP TABLE 或 CREATE VIEW?刪除數據庫呢?

我知道某些語句仍然執行,儘管像 PRINT “MESSAGE”。

我只是想了解仍然發生的事件類型。

對於允許在顯式事務中執行的語句(即BEGIN TRAN,或天堂禁止IMPLICIT_TRANSACTIONSON),我只知道以下兩個不會受 a 影響ROLLBACK(儘管從技術上講,兩者在某種意義上都有些“作弊”):

  1. 針對錶變數的 DML 語句(變數,甚至表變數,不參與事務)
  2. 通過連結伺服器執行的語句,並且OPENQUERY(即使使用環回伺服器定義連接到目前實例)如果您禁用了“遠端 proc 事務提升”的連結伺服器屬性(這樣它就不會嘗試在目前交易)。

OPENQUERY(禁用該選項)有效,因為它建立了單獨的連接。還有其他類似的方法可以在 T-SQL 中建立單獨的連接。David Browne 在評論中提到了擴展儲存過程。我們還可以將 SQLCLR 方法(無論它們以何種 T-SQL 對像類型公開)添加到該列表,但前提是進行正常/外部連接,enlist=false;在連接字元串中指定“ ”。我們可能還可以添加 OLE 自動化儲存過程(即sp_OA*),但我不是 100% 確定這些。 3. 可能有一個或兩個語句可以在顯式事務中執行但不能回滾,我可能在很多年前遇到過,但我不記得它是什麼並且可能是使用者錯誤(一些其他使用者,當然 ;-),因此您必須查閱文件以了解每個語句/操作的細節和/或盡可能多地測試(有時文件不正確……它發生了)。 4. 不確定這是否重要,因為它不是一個明確的更改,但不是可以回到事務開始之前的狀態(因為它甚至沒有意義):Tibor Karaszi 在一個評論“消費身份/序列值”可能符合條件。我已經測試並確認序列不會返回請求的值。

類似地,另一個不受回滾影響的數據庫狀態值,而不是具體的使用者數據,是目前/上次使用的時間戳值(這是每個數據庫,由系統變數返回@@DBTS;也通過測試確認) 5. 不確定這些是否計數,因為它們既不是顯式更改,也不是數據庫的狀態,但它們的值不受回滾的影響:在評論中,David Browne 提到SESSION_CONTEXT,這是每個會話的屬性。沿著同樣的構想,我們可以包括相關/相似的CONTEXT_INFO

如果一個游標剛剛執行了 100 次儲存過程並在每次迭代中更新了一個表,那麼所有這些更新都會回滾嗎?

是的,這就是顯式事務的目的:將語句組合成一個原子工作單元。

DDL 語句會回滾嗎?…例如 DROP TABLE 或 CREATE VIEW?刪除數據庫呢?

一些(也許大多數)是的。有些沒有。你可能應該測試一下。例如,這裡有一些回滾的 DDL:

USE [tempdb];

IF (OBJECT_ID(N'dbo.DropMe') IS NOT NULL)
BEGIN
 DROP TABLE dbo.DropMe;
END;

CREATE TABLE dbo.DropMe (col1 INT);

BEGIN TRAN;

DROP TABLE dbo.DropMe;

ROLLBACK TRAN;

SELECT * FROM dbo.[DropMe];

但是,相反,這裡有一些不能在顯式(或隱式)事務中執行的 DDL:

CREATE DATABASE [DropMe];
BEGIN TRAN;
DROP DATABASE [DropMe];
/*
Msg 574, Level 16, State 0, Line XXXXX
DROP DATABASE statement cannot be used inside a user transaction.
*/
ROLLBACK;

因此,只需使用上面的兩個範例,然後將它們修改為您好奇或需要明確答案的其他陳述。

引用自:https://dba.stackexchange.com/questions/253413