Có bốn chế độ giao dịch trong SQL Server. Một trong số đó là chế độ ngầm định.
Trong SQL Server, một giao dịch ngầm định là khi một giao dịch mới được bắt đầu một cách ngầm định khi giao dịch trước đó hoàn thành, nhưng mỗi giao dịch được hoàn thành một cách rõ ràng với một COMMIT
hoặc ROLLBACK
tuyên bố.
Điều này không được nhầm lẫn với chế độ tự động gửi, nơi giao dịch được bắt đầu và kết thúc ngầm.
Bốn phương thức giao dịch
SQL Server có thể hoạt động trong các chế độ giao dịch sau:
Chế độ giao dịch | Mô tả |
---|---|
Giao dịch tự động gửi | Mỗi câu lệnh riêng lẻ là một giao dịch. |
Giao dịch ngầm | Một giao dịch mới được bắt đầu một cách ngầm định khi giao dịch trước đó hoàn thành, nhưng mỗi giao dịch được hoàn thành một cách rõ ràng, thường với một COMMIT hoặc ROLLBACK tùy thuộc vào DBMS. |
Giao dịch rõ ràng | Bắt đầu rõ ràng bằng một dòng chẳng hạn như START TRANSACTION , START TRANSACTION hoặc tương tự, tùy thuộc vào DBMS, và cam kết rõ ràng hoặc quay lại với các tuyên bố có liên quan. |
Giao dịch theo loạt | Chỉ áp dụng cho nhiều bộ kết quả hoạt động (MARS). Một giao dịch rõ ràng hoặc ẩn bắt đầu trong một phiên MARS sẽ trở thành một giao dịch có phạm vi hàng loạt. |
Chế độ ngầm so với Tự động gửi
Trong SQL Server, một số câu lệnh nhất định sẽ tự động bắt đầu một giao dịch khi chúng chạy. Như thể chúng được đặt trước bởi một BEGIN TRANSACTION
vô hình tuyên bố.
Trong hầu hết các trường hợp, các giao dịch này cũng được cam kết ngầm, như thể có một COMMIT TRANSACTION
vô hình tuyên bố. Các giao dịch như vậy được cho là ở chế độ gửi tự động .
Trong các trường hợp khác, không có COMMIT TRANSACTION
ẩn để khớp với START TRANSACTION
ẩn tuyên bố. Giao dịch vẫn được tiến hành cho đến khi bạn cam kết rõ ràng hoặc khôi phục giao dịch đó bằng COMMIT TRANSACTION
hoặc ROLLBACK TRANSACTION
tuyên bố. Trong trường hợp này, giao dịch được cho là ở chế độ ẩn .
Việc giao dịch chạy ở chế độ ẩn hay chế độ tự động gửi tùy thuộc vào IMPLICIT_TRANSACTIONS
của bạn cài đặt.
Các tuyên bố bắt đầu một giao dịch ngầm
Các câu lệnh sau đây bắt đầu một giao dịch ngầm định trong SQL Server.
-
ALTER TABLE
-
START TRANSACTION
-
CREATE
-
DELETE
-
DROP
-
FETCH
-
GRANT
-
INSERT
-
OPEN
-
REVOKE
-
SELECT
(ngoại trừ những thứ không chọn từ bảng, chẳng hạn nhưSELECT GETDATE()
hoặcSELECT 1*1
) -
TRUNCATE TABLE
-
UPDATE
Bất kỳ khi nào bạn chạy các câu lệnh T-SQL này, bạn đang bắt đầu một giao dịch. Hầu hết thời gian giao dịch sẽ được tự động cam kết. Vì vậy, bạn đã bắt đầu và kết thúc giao dịch mà không cần phải làm như vậy một cách rõ ràng.
Tuy nhiên, tùy thuộc vào IMPLICIT_TRANSACTIONS
của bạn , bạn có thể cần phải cam kết giao dịch một cách rõ ràng.
Khi IMPLICIT_TRANSACTIONS
OFF
Khi IMPLICIT_TRANSACTIONS
của bạn cài đặt là OFF
, các câu lệnh trên thực hiện các giao dịch ở chế độ tự động gửi. Đó là, họ bắt đầu và kết thúc giao dịch một cách ngầm định.
Vì vậy, nó giống như có một BEGIN TRANSACTION
vô hình và một COMMIT TRANSACTION
ẩn , tất cả từ một câu lệnh.
Trong trường hợp này, bạn không cần phải làm bất cứ điều gì để cam kết hoặc khôi phục giao dịch. Nó đã được thực hiện cho bạn.
Khi IMPLICIT_TRANSACTIONS
ON
Khi IMPLICIT_TRANSACTIONS
của bạn cài đặt là ON
, các câu lệnh trên hoạt động hơi khác một chút.
Khi IMPLICIT_TRANSACTIONS
cài đặt là ON
, các câu lệnh trên nhận được START TRANSACTION
ẩn nhưng họ không nhận được COMMIT TRANSACTION
tương ứng tuyên bố.
Điều này có nghĩa là bạn cần phải tự mình cam kết hoặc hoàn nguyên giao dịch một cách rõ ràng.
Tuy nhiên, khi chế độ giao dịch là ẩn, không có BEGIN TRANSACTION
vô hình được phát hành nếu một giao dịch đang được thực hiện.
Ví dụ
Dưới đây là một ví dụ để chứng minh khái niệm này.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS OFF;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Kết quả:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Trong trường hợp này, tôi đặt IMPLICIT_TRANSACTIONS
thành OFF
và chạy SELECT
tuyên bố. Điều này có nghĩa là SELECT
câu lệnh chạy ở chế độ tự động gửi và do đó, giao dịch được bắt đầu và kết thúc ngầm.
@@TRANCOUNT
trả về 0
, có nghĩa là không có giao dịch nào đang chạy vào thời điểm đó.
Đây là một lần nữa, ngoại trừ lần này chúng tôi đặt IMPLICIT_TRANSACTIONS
thành ON
.
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
SELECT @@TRANCOUNT AS TransactionCount;
Kết quả:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) +--------------------+ | TransactionCount | |--------------------| | 1 | +--------------------+ (1 row affected)
@@TRANCOUNT
cuối cùng đang trả về giá trị 1
. Điều này có nghĩa là giao dịch của chúng tôi vẫn đang được tiến hành.
@@TRANCOUNT
trả về số lượng START TRANSACTION
các câu lệnh đã xảy ra trên kết nối hiện tại. Chúng tôi không phát hành một cách rõ ràng, nhưng một trong hai đã được phát hành ngầm.
Vì vậy, chúng tôi thực sự cần phải cam kết giao dịch này (hoặc khôi phục nó) để giảm @@TRANCOUNT
xuống 0
.
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Kết quả:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
Vì vậy, mã cho giao dịch ngầm của chúng tôi phải bao gồm COMMIT
tuyên bố:
SELECT @@TRANCOUNT AS TransactionCount;
SET IMPLICIT_TRANSACTIONS ON;
SELECT TOP 1 ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
SELECT @@TRANCOUNT AS TransactionCount;
Kết quả:
+--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected) Commands completed successfully. +-------------------------+----------------+ | ProductName | ProductPrice | |-------------------------+----------------| | Left handed screwdriver | 25.99 | +-------------------------+----------------+ (1 row affected) Commands completed successfully. +--------------------+ | TransactionCount | |--------------------| | 0 | +--------------------+ (1 row affected)
ANSI_DEFAULTS
Nếu bạn thấy rằng các giao dịch ngầm được kích hoạt bất ngờ, có thể là do ANSI_DEFAULTS
thiết lập.