Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách giao dịch ngầm hoạt động trong SQL Server

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ặc SELECT 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 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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sự khác biệt giữa đọc được cam kết và đọc có thể lặp lại

  2. Làm cách nào để trả về nhiều giá trị trong một cột (T-SQL)?

  3. Cách tìm bản ghi trùng lặp bằng cách sử dụng mệnh đề Group by và Have trong SQL Server - Hướng dẫn sử dụng SQL Server / TSQL Phần 132

  4. Cách tạo cơ sở dữ liệu trong SQL Server bằng TSQL hoặc GUI - Hướng dẫn SQL Server / TSQL Phần 24

  5. Đổi tên Kiểu dữ liệu do người dùng xác định trong SQL Server (T-SQL)